撸一个简易canvas动态时钟表盘

1,209 阅读2分钟

最近在看前端人都在看的红宝书,目前看到了canvas一节,结合前两天看到有大佬利用canvas制作了一个烟花特效,于是乎也想自己动手实现一个,巩固一下学习的效果,看树上给的🌰是一个表盘和指针,那我就来一个动态的时钟吧,话不多说,撸起来!

实现静态表盘

这一步比较简单,就是在同一个圆心画两个半径不同的圆

let canvas = document.getElementById('clock')
let context = canvas.getContext('2d')
// 圆心取页面正中心
let posX = window.innerWidth / 2 
let posY = window.innerHeight / 2
function createCanvas(){
  canvas.width = window.innerWidth
  canvas.height = window.innerHeight
  posX = window.innerWidth / 2 
  posY = window.innerHeight / 2
  createClock()
}
function clearCanvas(){
  context.fillStyle = '#000000'
  context.fillRect(0, 0, canvas.width, canvas.height) 
}
window.addEventListener('resize', createCanvas, false)
createCanvas()
function createClock(){
  let outRadius = 100 // 外表盘的半径
  let innerRadius = 90 // 内表盘半径


  context.beginPath()
  context.arc(posX, posY, outRadius, 0, Math.PI * 2, false)

  context.moveTo(posX + innerRadius, posY)
  context.arc(posX, posY, innerRadius, 0, Math.PI * 2, false)

  context.moveTo(posX + 5, posY)
  context.arc(posX, posY, 5, 0, Math.PI * 2, false)
  // 绘制时针
  context.moveTo(posX, posY)
  context.lineTo(posX, posY - 75)

  // 绘制分针
  context.moveTo(posX, posY)
  context.lineTo(posX - 55, posY)

  // 绘制秒针
  context.moveTo(posX, posY)
  context.lineTo(posX + 40, posY + 60)
  context.closePath()
  context.strokeStyle = '#ffffff'
  context.stroke()

  // 绘制表盘12个刻度数字
  for(let i = 1; i < 13; i++ ){
    let angle = 180 - 360 / 12 * i
    let radians = angle * Math.PI / 180
    let tX = Math.sin(radians) * innerRadius + posX
    let tY = Math.cos(radians) * innerRadius + posY
    context.font = "bold 14px Arial"; 
    context.textAlign = "center"; 
    context.textBaseline = "middle";
    context.fillStyle = '#ffffff'
    context.fillText(i, tX, tY)
  }
}

这时候就能看到静态表盘和指针就出来, 接下来就是计算各个指针的坐标,然后绘制出来,让表盘动起来

alt

计算各个指针的坐标

这也很简单,直接上代码

// 根据当前时间计算各指针的位置
function getClockPointPos(){
  let curDate = new Date()
  let curH = curDate.getHours() > 11? curDate.getHours() - 12: curDate.getHours() 
  let curM = curDate.getMinutes()
  let curS = curDate.getSeconds()
  let sW = 95 // 秒针的长度
  let mW = 75 // 分针的长度
  let hW = 55 // 时针的长度
  // 计算各个指针的角度
  let sAngle = Math.round(180 - curS / 60 * 360)
  let mAngle = Math.round(180 - curM / 60 * 360)
  let hAngle = Math.round(180 - (curH * 60 + curM) / 720 * 360)
  let sRadians = sAngle * Math.PI / 180
  let mRadians = mAngle * Math.PI / 180
  let hRadians = hAngle * Math.PI / 180

  let hObj = {
    x: Math.sin(hRadians) * hW + posX,
    y: Math.cos(hRadians) * hW + posY
  }
  let mObj = {
    x: Math.sin(mRadians) * mW + posX,
    y: Math.cos(mRadians) * mW + posY
  }
  let sObj = {
    x: Math.sin(sRadians) * sW + posX,
    y: Math.cos(sRadians) * sW + posY
  }
  return {
    hObj,
    mObj,
    sObj
  }
}

指针跑起来

接下来就是用刚才算出来的坐标画出指针的位置,修改之前绘制指针的代码

let oPos = getClockPointPos()
// 绘制时针
context.moveTo(posX, posY)
context.lineTo(oPos.hObj.x, oPos.hObj.y)

// 绘制分针
context.moveTo(posX, posY)
context.lineTo(oPos.mObj.x, oPos.mObj.y)

// 绘制秒针
context.moveTo(posX, posY)
context.lineTo(oPos.sObj.x, oPos.sObj.y)

这一步完成了就可以看到当前时间的争取指针位置了

alt

胜利就在眼前-- 让指针动起来

let animationId
function pointMove(){
  function move(){
    createClock()
    rid = requestAnimationFrame(move)
  }
  cancelAnimationFrame(rid)
  move()
}
function createCanvas(){
  canvas.width = window.innerWidth
  canvas.height = window.innerHeight
  posX = window.innerWidth / 2 
  posY = window.innerHeight / 2
  pointMove()
}

这是页面里的时钟就能一步一步的跑起来了,剩下的美化的部分就交给各位了。

结束,收功。