很多前端同学想学Canvas,但看到官方文档的API就头大,瞬间打消学习的兴趣。
今天咱们就使用Trae,用一个超简单的动态时钟,把Canvas的核心概念一次讲清楚。
先来看看最终的效果,是不是很优雅
为什么要学Canvas?
网页上的动画、游戏、图表等效果,很多都用Canvas。你可以理解为一块画布,让你用JavaScript画画,想要啥就画啥。
准备画布
arduino
<canvas id="clock" width="280" height="280"></canvas>
这一步相当于在页面上有了一块可以画画的画布。
注意:canvas的宽高要在标签里写,别在CSS设置,不然会导致画布的形状变形。
拿到画笔(使用js获取)
ini
const canvas = document.getElementById('clock');
const ctx = canvas.getContext('2d');
getContext('2d')就是拿到2D画笔,有了它才能开始画画。
第三步:坐标系搞清楚
Canvas的坐标原点在左上角,向右是x轴正方向,向下是y轴正方向。为了让时钟居中,咱们把原点移到画布中心:
ini
const radius = canvas.width / 2;
ctx.translate(radius, radius);
现在(0,0)点就是画布中心了,画什么都方便。
第四步:画圆(表盘)
时钟就是个圆,用arc方法:
ini
ctx.beginPath();
ctx.arc(0, 0, radius * 0.95, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();

arc(x, y, 半径, 起始角度, 结束角度),角度用弧度表示,2π就是一圈。
第五步:画刻度
时钟有12个小时刻度,每个刻度角度是30度(2π/12)。用循环画:
ini
for (let num = 1; num <= 12; num++) {
const angle = (num * Math.PI) / 6;
ctx.rotate(angle);
ctx.moveTo(0, -radius * 0.92);
ctx.lineTo(0, -radius * 0.82);
ctx.stroke();
ctx.rotate(-angle); // 记得转回来
}
rotate是旋转画布,画完要转回来,不然下一条线就歪了。
第六步:画数字
数字12的位置在正上方,角度是-90度(-π/2):
ini
ctx.font = "30px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("12", 0, -radius * 0.68);

第七步:让指针动起来
指针就是三条线,根据当前时间计算角度:
ini
const now = new Date();
const hour = now.getHours();
const minute = now.getMinutes();
const second = now.getSeconds();
// 时针角度
const hourAngle = ((hour % 12) * 30 + minute * 0.5) * Math.
PI / 180;
// 分针角度
const minuteAngle = (minute * 6 + second * 0.1) * Math.
PI / 180;
// 秒针角度
const secondAngle = (second * 6) * Math.PI / 180;
第八步:动画效果
用setInterval让时钟动起来:
scss
function drawClock() {
ctx.clearRect(-radius, -radius, canvas.width, canvas.
height);
// 重画所有内容
}
setInterval(drawClock, 1000);
查看画面,功能是对的,但是歪的,刻度盖住了,让Trae修复一下
Trae的第一次修复
还是有问题,再次让Trae修复,这波可真是一波三折,好在最后还是实现了
完整思路
1.先画静态的表盘(圆+刻度+数字)
2.再画动态的指针(根据时间计算角度)
- 用定时器每秒更新一次
小技巧
- 先画大部件,再画小细节
- 用save()和restore()保存和恢复画布状态
- 角度计算用弧度制,180度=π弧度
看完这个,你应该明白Canvas的基本用法了。试着改改颜色、大小,或者加个日期显示,动手最重要!