用canvas绘制时钟

1,246 阅读2分钟

学习了canvas基础,现在用学到的知识点绘制一个时钟。绘制过程可分解为以下步骤:

创建canvas画布

创建canvas元素,设置画布大小为300*300

  <canvas id="canvas" width="300" height="300"></canvas>

获取渲染上下文

首先获取canvas元素,通过getContext获取渲染上下文。

ctx = document.getElementById('canvas').getContext('2d');

将画布圆心移动到中心位置

为了方便计算,将画布圆心平移到(150,150),保存一下当前状态。后面绘制的图形都基于该状态进行绘制。

ctx.save()//保存初始状态
ctx.translate(150, 150) 
ctx.save()//保存坐标平移后的状态

绘制时钟的圆形外轮廓

ctx.beginPath()    
ctx.lineWidth = 5
ctx.arc(0,0,140,0,360*Math.PI/180)
ctx.stroke()

image.png

绘制时针标记

有12个时针,每个时针间隔30°,通过循环绘制出12个时针。

for(let i=0; i< 12; i++){
  ctx.beginPath()
  ctx.moveTo(80, 0)
  ctx.lineTo(100, 0)
  ctx.rotate(30*Math.PI/180)
  ctx.stroke()
}

image.png

绘制分针标记

分针和时针标记,将钟盘分割成了60分,通过循环绘制出分针标记。

ctx.lineWidth = 2
ctx.strokeStyle = "#666"    
for(let i=0; i<60; i++){
  ctx.beginPath()
  ctx.moveTo(90,0)
  ctx.lineTo(100, 0)
  ctx.rotate(6*Math.PI/180)
  if(i%5==0) continue;
  ctx.stroke()
}

image.png

绘制时针、分针、秒针

绘制时针、分针、秒针前,要重置一下状态,以保证画布没有被旋转。

//时针
ctx.restore()//恢复坐标平移后的状态
ctx.save()//保存坐标平移后的状态
ctx.beginPath()
ctx.lineWidth = 6
ctx.lineCap = "round"
ctx.moveTo(0,0)
ctx.lineTo(50, 0)
ctx.stroke()
//分针
ctx.restore()//恢复坐标平移后的状态
ctx.save()//保存坐标平移后的状态
ctx.beginPath()
ctx.lineWidth = 4
ctx.moveTo(0,0)
ctx.lineTo(65,0)
ctx.stroke()
//秒针
ctx.restore()//恢复坐标平移后的状态
ctx.beginPath()
ctx.lineWidth = 2
ctx.moveTo(0,0)
ctx.lineTo(80,0)
ctx.strokeStyle="red"
ctx.stroke()
ctx.restore()//恢复到初始状态

image.png

指针指向正确的时标

上面代码完成了基本图形的绘制,接下来需要让时针、分针、秒针指向正确的时标。 根据当前时间计算出时针、分针、秒针旋转的弧度。 代码如下:

    const date = new Date();
    const hour = date.getHours()
    const minute = date.getMinutes()
    const second = date.getSeconds()
    let hourDegree = (hour % 12 / 12 * 360 *  Math.PI / 180 + minute / 60 * 30 * Math.PI / 180) - Math.PI/2
    let minuteDegree =  minute / 60 * 360 * Math.PI / 180 - Math.PI/2
    let secondDegree = second / 60 * 360 * Math.PI / 180 - Math.PI/2

image.png

让时钟动起来

将上面的代码封装成一个函数clock,使用window.requestAnimationFrame()方法在屏幕每次刷新之前,绘制时钟。