前言
今天在设闹钟的时候发现手机上的那个世界时钟挺好看的,正好最近在学canvas,就心血来潮想将它复刻出来
原版
首先将时针、分针和刻度都画出来
时针,可以根据当前时间算出时针转过的角度,如果不考虑分针对时针的影响,那时针当前转过的角度就是(2π/12) h(h是当前小时数),再叫上分钟数(一开始我忘了,后来越看越不对劲,经过对比发现,我忘记了时针转动的角度还和分钟有关)。那时钟转过的角度就是(2π/12) h+(2π/6012) m(m是当前分钟数)
分针就类似时针
刻度可以通过一个60次的循环,每循环一次画一个刻度,并判断当前刻度是否是当前秒数。
这样子就已经将大体弄出来了,其他的数字之类的就通过fillText()画上去,中间的圆环是一个有颜色的大圆中间一个白色小圆
注意:如果分钟是小于10的数时,要补个0,可以通过padStart(2,0)完成,小时也一样
效果:
代码如下:
<canvas id="clock" width="300" height="300"></canvas>
<script>
const clock = document.getElementById("clock")
const ctx = clock.getContext("2d")
fn()
function fn() {
const time = Date.now()
const h1 = new Date(time).getHours()
const h = h1 % 12
const m = new Date(time).getMinutes()
const s = new Date(time).getSeconds()
ctx.save()
ctx.clearRect(0, 0, 300, 300)
ctx.translate(120, 120)
ctx.save()
//分
ctx.rotate(2 * Math.PI * m / 60 + s * 2 * Math.PI / 3600)
ctx.beginPath()
ctx.moveTo(0, -50)
ctx.lineTo(0, -85)
ctx.lineWidth = 5
ctx.lineCap = "round"
ctx.stroke()
ctx.closePath()
ctx.restore()
ctx.save()
//时
ctx.rotate(2 * Math.PI * h / 12 + m * 2 * Math.PI / 720)
ctx.beginPath()
ctx.moveTo(0, -50)
ctx.lineTo(0, -75)
ctx.lineWidth = 10
ctx.strokeStyle = "red"
ctx.lineCap = "round"
ctx.stroke()
ctx.closePath()
ctx.restore()
ctx.save()
ctx.font = "bold 14px Arial"
ctx.textAlign = "center"
ctx.textBaseLine = "middle"
ctx.fillText("12", 0, -95)
ctx.fillText("3", 100, 4)
ctx.fillText("6", 0, 103)
ctx.fillText("9", -100, 4)
for (let i = 0; i < 60; i++) {
if (i === s) {
ctx.lineWidth = 5
ctx.strokeStyle = "red"
ctx.beginPath()
ctx.moveTo(0, -104)
ctx.lineTo(0, -90)
ctx.lineCap = "round"
ctx.stroke()
ctx.closePath()
} else {
ctx.strokeStyle = "rgba(0,0,0,.3)"
if (i % 5 === 0 && i !== 0 && i !== 15 && i !== 30 && i !== 45) {
ctx.lineWidth = 3
ctx.lineCap = "round"
ctx.beginPath()
ctx.moveTo(0, -100)
ctx.lineTo(0, -94)
ctx.stroke()
ctx.closePath()
} else if (i % 5 !== 0) {
ctx.lineWidth = 1
ctx.beginPath()
ctx.moveTo(0, -100)
ctx.lineTo(0, -98)
ctx.stroke()
ctx.closePath()
}
}
ctx.rotate(2 * Math.PI / 60)
}
ctx.beginPath()
ctx.arc(0, 0, 40, 0, 2 * Math.PI)
ctx.fillStyle = "rgba(0,0,0,0.1)"
ctx.fill()
ctx.closePath()
ctx.beginPath()
ctx.arc(0, 0, 20, 0, 2 * Math.PI)
ctx.fillStyle = "white"
ctx.fill()
ctx.closePath()
ctx.fillStyle = "black"
ctx.font = "bold 30px Arial"
ctx.fillText(`${(h1 + "").padStart(2, 0)}:${(m + "").padStart(2, 0)}`, 0, 10)
ctx.restore()
ctx.restore()
}
setInterval(fn, 1000)
</script>