likes
comments
collection
share

Canvas实战:使用Canvas绘制时钟

作者站长头像
站长
· 阅读数 17

Canvas实战:使用Canvas绘制时钟

钟类

class Clock {
  private ctx
  // 中心点
  private center: { x: number; y: number }
  constructor(private canvas: HTMLCanvasElement, private radius: number) {
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')!
    // 钟的半径
    this.radius = radius
    this.center = { x: this.canvas.width / 2, y: this.canvas.height / 2 }
  }
  draw() {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
  }
}

绘制时钟边框和圆心

// 绘制时钟边框和圆心
drawClockCircle() {
    // 绘制时钟边框,即一个圆
    this.ctx.beginPath()
    this.ctx.arc(this.center.x, this.center.y, this.radius, 0, 2 * Math.PI)
    this.ctx.closePath()
    this.ctx.strokeStyle = '#000'
    this.ctx.stroke()
    // 绘制圆心
    this.ctx.beginPath()
    this.ctx.arc(this.canvas.width / 2, this.canvas.height / 2, 6, 0, 2 * Math.PI)
    this.ctx.closePath()
    this.ctx.fillStyle = '#000'
    this.ctx.fill()
}

Canvas实战:使用Canvas绘制时钟

绘制1~12的数字

// 绘制1~12的数字
 drawClockDial() {
    this.ctx.save()
    // 将原点移动到中心点
    this.ctx.translate(this.center.x, this.center.y)
    // 设置一些文字的基础样式
    this.ctx.textBaseline = 'middle'
    this.ctx.font = '20px'
    this.ctx.textAlign = 'center'
    // 偏移量,不然会与后续数字重叠
    const offset = 24
    const r = this.radius - offset
    for (let i = 1; i <= 12; i++) {
      const angel = (360 / 12) * i
      // 转弧度
      const radian = (angel / 180) * Math.PI
      const x = r * Math.sin(radian)
      const y = -r * Math.cos(radian)
      this.ctx.fillText(`${i}`, x, y)
    }
    this.ctx.restore()
}

Canvas实战:使用Canvas绘制时钟

绘制刻度线

包括绘制小时线(共12根)和分钟线(共60根)

// 绘制刻度线
drawClockMark() {
    // 画小时线
    this.ctx.save()
    // 将原点移动到中心点
    this.ctx.translate(this.center.x, this.center.y)
    this.ctx.lineWidth = 4
    for (let i = 1; i <= 12; i++) {
      this.ctx.beginPath()
      this.ctx.moveTo(this.radius, 0)
      this.ctx.lineTo(this.radius - 10, 0)
      this.ctx.rotate((30 * Math.PI) / 180)
      this.ctx.stroke()
    }
    this.ctx.restore()
    // 画分钟线
    this.ctx.save()
    // 将原点移动到中心点
    this.ctx.translate(this.center.x, this.center.y)
    this.ctx.lineWidth = 2
    for (let i = 0; i < 60; i++) {
      this.ctx.beginPath()
      this.ctx.moveTo(this.radius, 0)
      this.ctx.lineTo(this.radius - 6, 0)
      this.ctx.rotate((6 * Math.PI) / 180)
      this.ctx.stroke()
    }
    this.ctx.restore()
}

Canvas实战:使用Canvas绘制时钟

绘制时针、分针和秒针

绘制时针

// 绘制时针
drawHour() {
    this.ctx.save()
    // 将原点移动到中心点
    this.ctx.translate(this.center.x, this.center.y)
    this.ctx.lineWidth = 5
    const r = this.radius - 60
    const now = new Date()
    const hours = now.getHours()
    const minutes = now.getMinutes()
    const angel = (360 / 12) * (hours % 12) + 30 * (minutes / 60)
    // 转弧度
    const radian = (angel / 180) * Math.PI
    const x = r * Math.sin(radian)
    const y = -r * Math.cos(radian)
    this.ctx.beginPath()
    this.ctx.moveTo(0, 0)
    this.ctx.lineTo(x, y)
    this.ctx.closePath()
    this.ctx.stroke()
    this.ctx.restore()
}

Canvas实战:使用Canvas绘制时钟

绘制分针和秒针 绘制分钟和秒针的方法是很类似的,只分针和秒针的角度和宽度长度的参数不同,我们通过上面绘制时针的方法封装为通用方法。

// 绘制时针分针和秒针的通用方法
drawClockHand(angel: number, lineWidth: number, length: number) {
    this.ctx.save()
    // 将原点移动到中心点
    this.ctx.translate(this.center.x, this.center.y)
    this.ctx.lineWidth = lineWidth
    // 转弧度
    const radian = (angel / 180) * Math.PI
    const x = length * Math.sin(radian)
    const y = -length * Math.cos(radian)
    this.ctx.beginPath()
    this.ctx.moveTo(0, 0)
    this.ctx.lineTo(x, y)
    this.ctx.closePath()
    this.ctx.stroke()
    this.ctx.restore()
}
// 绘制时针
drawHour() {
    const now = new Date()
    const hours = now.getHours()
    const minutes = now.getMinutes()
    const angel = (360 / 12) * (hours % 12) + 30 * (minutes / 60)
    this.drawClockHand(angel, 5, this.radius - 60)
}
// 绘制分针
drawMinute() {
    const now = new Date()
    const minutes = now.getMinutes()
    const seconds = now.getSeconds()
    const angel = 360 * (minutes / 60) + 6 * (seconds / 60)
    this.drawClockHand(angel, 4, this.radius - 40)
}
// 绘制分针
drawSecond() {
    const now = new Date()
    const seconds = now.getSeconds()
    const angel = 360 * (seconds / 60)
    this.drawClockHand(angel, 2, this.radius - 20)
}

Canvas实战:使用Canvas绘制时钟

让时针动起来