我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!
写在前面
本文用canvas+vue画一个简单的时钟。
代码块
代码说明
- 创建画布,对画布进行初始化设置,并调用绘制时钟的方法
<canvas id="Canvas" width="500" height="300"></canvas>
initChavas() {
this.ctx = document.getElementById("Canvas").getContext("2d");
this.clock();
},
clock() {
this.ctx.save(); // 保存当前状态
this.ctx.clearRect(0, 0, 500, 500); // 清除画布上矩形区域(0, 0, 500, 500)的内容
this.ctx.translate(250, 250); // 将(250,250)设置成(0,0)
this.ctx.strokeStyle = "black"; // 设置画笔颜色
this.ctx.fillStyle = "white"; // 设置填充颜色
this.ctx.lineWidth = 8; // 设置线条宽度
this.ctx.lineCap = "round"; // 设置线条结束样式
this.ctx.rotate(-Math.PI / 2); // 逆时针旋转90度
}
- 绘制表示时的点
因为一开始将(250,250)设置成(0,0),所以(100,0)->(120,0)在整个画布上实际是(350,250)->(370,250)
并且我们需要保存一下状态,否则在下面改变样式的时候会被一起改变
this.ctx.save(); // 保存当前状态
for (let i = 0; i < 12; i++) {
this.ctx.beginPath(); // 开始绘制
this.ctx.moveTo(100, 0); // 绘制开始位置
this.ctx.lineTo(120, 0); // 绘制结束位置
this.ctx.stroke(); // 实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径
this.ctx.rotate(Math.PI / 6); // 每画一个顺时针旋转30度
}
this.ctx.restore();
- 绘制表示分的点
this.ctx.save(); // 保存当前状态
this.ctx.lineWidth = 5; // 线段的宽度改成5
this.ctx.strokeStyle = "#333"; // 颜色也改一下
for (let i = 0; i < 60; i++) {
if (i % 5 != 0) {
this.ctx.beginPath();
this.ctx.moveTo(117, 0);
this.ctx.lineTo(120, 0);
this.ctx.stroke();
}
this.ctx.rotate(Math.PI / 30); // 每画一个顺时针旋转6度
}
this.ctx.restore();
- 获取当前时间
let now = new Date(); // 获取当前时间
let sec = now.getSeconds(); // 获取当前秒
let min = now.getMinutes(); // 获取当前分
let hr = now.getHours(); // 获取当前时
hr = hr >= 12 ? hr - 12 : hr; // 时按12小时制
- 绘制时针
this.ctx.save();
this.ctx.rotate(
hr * (Math.PI / 6) + (Math.PI / 360) * min + (Math.PI / 21600) * sec
);
this.ctx.lineWidth = 14;
this.ctx.beginPath(); // 开始绘制
this.ctx.moveTo(-20, 0);
this.ctx.lineTo(80, 0);
this.ctx.stroke(); // 实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径
this.ctx.restore();
- 绘制分针
this.ctx.save();
this.ctx.rotate((Math.PI / 30) * min + (Math.PI / 1800) * sec);
this.ctx.lineWidth = 10;
this.ctx.beginPath();
this.ctx.moveTo(-28, 0);
this.ctx.lineTo(112, 0);
this.ctx.stroke(); // 实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径
this.ctx.restore();
- 绘制秒针
this.ctx.save();
this.ctx.rotate((sec * Math.PI) / 30);
this.ctx.strokeStyle = "red";
this.ctx.fillStyle = "red"; // 填充颜色
this.ctx.lineWidth = 6;
this.ctx.beginPath();
this.ctx.moveTo(-30, 0);
this.ctx.lineTo(83, 0);
this.ctx.stroke();
this.ctx.beginPath();
this.ctx.arc(0, 0, 8, 0, Math.PI * 2, true); // 绘制圆(中心x,中心y,半径,起始角度,结束角度,true逆时针画圆/false顺时针画圆)
this.ctx.fill(); // 填充颜色
this.ctx.restore();
- 绘制外框
this.ctx.beginPath(); // 开始绘制
this.ctx.lineWidth = 10; // 线的宽度
this.ctx.strokeStyle = "blue"; // 线的颜色
this.ctx.arc(0, 0, 130, 0, Math.PI * 2, true); // 绘制圆(中心x,中心y,半径,起始角度,结束角度,true逆时针画圆/false顺时针画圆)
this.ctx.stroke();
最终效果:
- 帧动画
window.requestAnimationFrame(this.clock);
写在最后
以上就是所有代码,参考js:动画时钟