一直很好奇Canvas,以前也没用过,今天专门对着MDN的文档认真学了大半天,大概了解了它的Api,一天快结束了,画个钟吧。想到以前学习CSS动画,最后也是画了个钟。
Clock,确实是很有代表性的东西
大部分代码找着MDN文档Copy的,尝试改了下UI,唯一突破就是加了数字。
因为要加数字,还专门去搜索如何计算圆周上点的坐标, 又是sin,cos,当年我的三角函数学得还不错,如今全忘了。
看到transform这个API,又去温习了一下矩阵,大学线性代数没学好有点可惜,还想起来那个女老师,名字我都没忘记。好吧,实际上我连矩阵乘法都忘的干干净净了。
Canvas的api不复杂,但是要想用好,还得数学好呀,突然觉得好难,又是从入门到放弃的一天,害~
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const canvasRef = ref()
let ctx: any = null
onMounted(() => {
ctx = canvasRef.value.getContext('2d')
clock()
})
function clock() {
var now = new Date()
ctx.save()
ctx.clearRect(0, 0, 500, 500)
ctx.translate(200, 200)
// ctx.scale(1, 1)
ctx.rotate(-Math.PI / 2)
ctx.strokeStyle = '#b9b9b9'
ctx.fillStyle = '#b9b9b9'
ctx.lineWidth = 4
ctx.lineCap = 'round'
ctx.lineCap = 'square'
ctx.arc(0, 0, 150, 0, Math.PI * 2, true)
ctx.fillStyle = '#4d4d4d'
ctx.fill()
// Hour marks
ctx.save()
for (var i = 0; i < 12; i++) {
ctx.beginPath()
ctx.rotate(Math.PI / 6)
ctx.moveTo(136, 0)
ctx.lineTo(142, 0)
ctx.stroke()
}
ctx.restore()
// text marks
ctx.save()
ctx.rotate(Math.PI / 2)
for (var i = 1; i < 13; i++) {
ctx.font = '18px arial'
ctx.fillStyle = '#b9b9b9'
let text = ctx.measureText(i)
let x = 118 * Math.cos((30 * (i - 3) * Math.PI) / 180) - text.width / 2
let y = 118 * Math.sin((30 * (i - 3) * Math.PI) / 180) + 7
ctx.fillText(i, x, y)
}
ctx.restore()
// Minute marks
ctx.save()
ctx.lineWidth = 2
ctx.stokeStyle = '#eee'
for (i = 0; i < 60; i++) {
if (i % 5 != 0) {
ctx.beginPath()
ctx.moveTo(138, 0)
ctx.lineTo(142, 0)
ctx.stroke()
}
ctx.rotate(Math.PI / 30)
}
ctx.restore()
var sec = now.getSeconds()
var min = now.getMinutes()
var hr = now.getHours()
hr = hr >= 12 ? hr - 12 : hr
ctx.fillStyle = 'black'
// write Hours
ctx.save()
ctx.rotate(hr * (Math.PI / 6) + (Math.PI / 360) * min + (Math.PI / 21600) * sec)
ctx.lineWidth = 8
ctx.beginPath()
ctx.moveTo(-20, 0)
ctx.lineTo(80, 0)
ctx.strokeStyle = '#222'
ctx.stroke()
ctx.beginPath()
ctx.moveTo(30, 0)
ctx.lineTo(80, 0)
ctx.strokeStyle = '#eee'
ctx.stroke()
ctx.restore()
// write Minutes
ctx.save()
ctx.rotate((Math.PI / 30) * min + (Math.PI / 1800) * sec)
ctx.lineWidth = 6
ctx.beginPath()
ctx.moveTo(-28, 0)
ctx.lineTo(30, 0)
ctx.strokeStyle = '#222'
ctx.stroke()
ctx.beginPath()
ctx.moveTo(30, 0)
ctx.lineTo(100, 0)
ctx.strokeStyle = '#eee'
ctx.stroke()
ctx.restore()
// Write seconds
ctx.save()
ctx.rotate((sec * Math.PI) / 30)
ctx.strokeStyle = '#D40000'
ctx.fillStyle = '#D40000'
ctx.lineWidth = 3
ctx.beginPath()
ctx.moveTo(-30, 0)
ctx.lineTo(90, 0)
ctx.stroke()
ctx.beginPath()
ctx.arc(0, 0, 10, 0, Math.PI * 2, true)
ctx.fill()
ctx.beginPath()
ctx.arc(95, 0, 5, 0, Math.PI * 2, true)
ctx.stroke()
ctx.fillStyle = 'rgba(0,0,0,0)'
ctx.arc(0, 0, 3, 0, Math.PI * 2, true)
ctx.fill()
ctx.restore()
ctx.beginPath()
ctx.lineWidth = 6
ctx.strokeStyle = '#494949'
ctx.arc(0, 0, 150, 0, Math.PI * 2, true)
ctx.stroke()
ctx.restore()
window.requestAnimationFrame(clock)
}
window.requestAnimationFrame(clock)
</script>