用JS|用JS Canvas画一个腕表??送给自己
没钱买表 某前端程序员竟然 用代码画了个表
文章图片
clock.jpeg 在线Demo https://codepen.io/DiscoverForever/pen/dyXKaqb
HTML代码
test - 锐客网 html,
body {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}#canvas {
width: 200px;
height: 200px;
}
Javascript代码
function init() {
const canvas = document.getElementById('canvas')
const width = canvas.width
const height = canvas.height
canvas.style.width = width + 'px'
canvas.style.height = height + 'px'
canvas.height = height * devicePixelRatio
canvas.width = width * devicePixelRatio
let ctx = null
if (canvas.getContext) {
ctx = canvas.getContext('2d')
} else {
alert('该浏览器暂不支持Canvas')
return
}
setInterval(() => {
// 清空画布
canvas.height = height * devicePixelRatio
canvas.width = width * devicePixelRatio
run(ctx)
}, 1000)
}function run(ctx) {const date = new Date()
renderCircle(ctx, 100, 100, 99, 'grey')
renderCircle(ctx, 100, 100, 94, 'black')
renderHourHand(ctx, getHourHandAngle(date.getHours()))
renderMinuteHand(ctx, getMinuteHandAngle(date.getMinutes()))
renderSecondHand(ctx, getSecondHandAngle(date.getSeconds()))
artCenterCircle(ctx)
renderScaleLabel(ctx)
renderHourScale(ctx)
renderMinuteScale(ctx)}/**
* 获取时针偏转角度
* @param {*} second
* @returns
*/
function getHourHandAngle(hour) {
let currentHour = null
if (hour <= 12) {
currentHour = hour
} else {
currentHour = hour - 12
}
return currentHour * 30 * (Math.PI / 180)
}/**
* 获取分针偏转角度
* @param {*} second
* @returns
*/
function getMinuteHandAngle(minute) {
return minute * 6 * (Math.PI / 180)
}/**
* 获取秒针偏转角度
* @param {*} second
* @returns
*/
function getSecondHandAngle(second) {
return second * 6 * (Math.PI / 180)
}/**
* 画圆
*/
function renderCircle(ctx, x, y, radius, color, lineWidth = 1) {
ctx.beginPath()
ctx.strokeStyle = color
ctx.lineWidth = lineWidth
ctx.arc(x * devicePixelRatio, y * devicePixelRatio, radius * devicePixelRatio, 0, 2 * Math.PI, false)
ctx.stroke()
ctx.closePath()
}/**
* 画时针
* @param {*} ctx
* @param {*} angle
*/
function renderHourHand(ctx, angle) {
ctx.beginPath()
ctx.save()
ctx.translate(100 * devicePixelRatio, 100 * devicePixelRatio)
ctx.rotate(angle)
ctx.strokeStyle = 'black'
ctx.lineWidth = 10
ctx.moveTo(0, 0)
ctx.lineTo(0, -40 * devicePixelRatio)
ctx.stroke()
ctx.restore()
ctx.closePath()
}/**
* 画分针
* @param {*} ctx
* @param {*} angle
*/
function renderMinuteHand(ctx, angle) {
ctx.beginPath()
ctx.save()
ctx.translate(100 * devicePixelRatio, 100 * devicePixelRatio)
ctx.rotate(angle)
ctx.strokeStyle = 'black'
ctx.lineWidth = 6
ctx.moveTo(0, 0)
ctx.lineTo(0, -60 * devicePixelRatio)
ctx.stroke()
ctx.restore()
ctx.closePath()
}/**
* 画秒针
* @param {*} ctx
* @param {*} angle
*/
function renderSecondHand(ctx, angle) {
ctx.beginPath()
ctx.save()
ctx.translate(100 * devicePixelRatio, 100 * devicePixelRatio)
ctx.rotate(angle)
ctx.strokeStyle = 'black'
ctx.lineWidth = 2
ctx.moveTo(0, 0)
ctx.lineTo(0, -90 * devicePixelRatio)
ctx.stroke()
ctx.restore()
ctx.closePath()}/**
* 表心
* @param {*} ctx
*/
function artCenterCircle(ctx) {
ctx.beginPath()
ctx.lineWidth = 1
ctx.fillStyle = 'black'
ctx.arc(100 * devicePixelRatio, 100 * devicePixelRatio, 4 * devicePixelRatio, 0, 2 * Math.PI, false)
ctx.fill()
}/**
* 画表盘刻度
* @param {*} ctx
*/
function renderScale(ctx) {
const lables = genClockScale(100, 100, 94)
ctx.beginPath()
lables.forEach(label => {
ctx.moveTo(label.x, label.y)
ctx.lineTo(100 * devicePixelRatio, 100 * devicePixelRatio)
})
ctx.stroke()
}/**
* 画小时刻度
*/
function renderHourScale(ctx) {
for (var i = 0;
i < 12;
i++) {
ctx.beginPath()
ctx.save()
ctx.translate(102 * devicePixelRatio, 98 * devicePixelRatio)
ctx.lineWidth = 2
ctx.strokeStyle = 'black'
ctx.rotate(i * 30 * Math.PI / 180)
ctx.moveTo(0, -94 * devicePixelRatio)
ctx.lineTo(0, -89 * devicePixelRatio)
ctx.stroke()
ctx.restore()
ctx.closePath()
}
}/**
* 画分刻度
*/
function renderMinuteScale(ctx) {
for (var i = 0;
i < 60;
i++) {
ctx.beginPath()
ctx.save()
ctx.translate(102 * devicePixelRatio, 98 * devicePixelRatio)
ctx.lineWidth = 1
ctx.strokeStyle = 'black'
ctx.rotate(i * 6 * Math.PI / 180)
ctx.moveTo(0, -94 * devicePixelRatio)
ctx.lineTo(0, -92 * devicePixelRatio)
ctx.stroke()
ctx.restore()
ctx.closePath()
}
}/**
* 画表盘数字
*/
function renderScaleLabel(ctx) {
const lables = genClockScale(100, 100, 82)
ctx.beginPath()
ctx.font = `${10 * devicePixelRatio}px Pingfang`
ctx.translate(-2 * devicePixelRatio, 2 * devicePixelRatio)
lables.forEach(label => ctx.fillText(label.text, label.x, label.y))
ctx.translate(0, 0)
ctx.closePath()
}
/**
* 获取刻度坐标
* @param {*} x 圆心x
* @param {*} y 圆心y
* @param {*} radius 半径
* @returns
*/
function genClockScale(ccX, ccY, radius, offset = 0) {
const lables = [9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8]
return lables.map((label, index) => {
const angle = Math.PI * 2 / 12 * index
let x = ccX - radius * Math.cos(angle) + offset
let y = ccY - radius * Math.sin(angle) + offset
return {
angle,
text: label,
x: x * devicePixelRatio,
y: y * devicePixelRatio,
}
})
}window.onload = init
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- 画画吗()
- JS中的各种宽高度定义及其应用
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- 涉毒患者(新诗)
- 参保人员因患病来不及到指定的医疗机构就医,能否报销医疗费用()
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询