用vue+canvas画一个简单的时钟

324 阅读2分钟

我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!


写在前面

本文用canvas+vue画一个简单的时钟。

代码块

代码说明

  1. 创建画布,对画布进行初始化设置,并调用绘制时钟的方法
<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度
}
  1. 绘制表示时的点

因为一开始将(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();
  1. 绘制表示分的点
  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();
  1. 获取当前时间
let now = new Date(); // 获取当前时间
let sec = now.getSeconds(); // 获取当前秒
let min = now.getMinutes(); // 获取当前分
let hr = now.getHours(); // 获取当前时
hr = hr >= 12 ? hr - 12 : hr; // 时按12小时制
  1. 绘制时针
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();
  1. 绘制分针
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();
  1. 绘制秒针
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();
  1. 绘制外框
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();

最终效果:

image.png

  1. 帧动画
window.requestAnimationFrame(this.clock);

写在最后

以上就是所有代码,参考js:动画时钟