canvas角度与弧度之间的转化制作时钟

216 阅读1分钟

canvas绘图

重点: 角度与弧度之间的转化, eg: radian=2 * Math.PI angle=Math.cos(radian); angle=Math.sin(radian); length=Math.cos(radian) * radius

<template>
  <div class="Test_page">
    <canvas id="clock" width="360" height="360"></canvas>
  </div>
</template>
<script>
export default {
  name: "TestPage",
  data () {
    return {
      dom: null,
      ctx: null,
      width: 0,
      radius: 0,
      rem: 0
    }
  },
  methods: {
    //制作时钟背景
    drawBackground () {
      this.ctx.save()
      this.ctx.translate(this.radius, this.radius)
      this.ctx.beginPath()
      this.ctx.lineWidth = 10 * this.rem
      this.ctx.arc(0, 0, this.radius - this.ctx.lineWidth / 2, 2 * Math.PI, false)
      this.ctx.stroke()
      // 画外圆结束
      const hourNumbers = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]
      const singleRadianHour = 2 * Math.PI / 12
      this.ctx.font = `${18 * this.rem}px Arial`;
      this.ctx.textAlign = "center";
      this.ctx.textBaseline = "middle";
      //钟点文字
      hourNumbers.forEach((text, index) => {
        const radian = singleRadianHour * index
        const x = Math.cos(radian) * (this.radius - 32 * this.rem)
        const y = Math.sin(radian) * (this.radius - 32 * this.rem)
        this.ctx.fillText(text, x, y)
      })
      //60个分钟点
      for (let i = 0; i < 60; i++) {
        this.ctx.beginPath()
        const dotX = Math.cos(singleRadianHour / 5 * i) * (this.radius - 18 * this.rem)
        const dotY = Math.sin(singleRadianHour / 5 * i) * (this.radius - 18 * this.rem)
        if (i % 5 === 0) {
          this.ctx.fillStyle = "#000000";//整点颜色加深
        } else {
          this.ctx.fillStyle = "#eeeeee";
        }
        this.ctx.arc(dotX, dotY, 2 * this.rem, 0, 2 * Math.PI, false)
        this.ctx.fill()
      }
    },
    //时针
    drawHour (hour, minute) {
      this.ctx.save()
      this.ctx.beginPath();
      const rad = 2 * Math.PI / 12 * hour
      const radM = 2 * Math.PI / 12 / 60 * minute
      this.ctx.rotate(rad + radM)
      this.ctx.lineWidth = 6 * this.rem
      this.ctx.lineCap = 'round'
      this.ctx.moveTo(0, 10 * this.rem)
      this.ctx.lineTo(0, -this.radius / 3)
      this.ctx.stroke()
      this.ctx.restore()
    },
    //分针
    drawMinute (minute) {
      this.ctx.save()
      this.ctx.beginPath();
      const rad = 2 * Math.PI / 60 * minute
      // const radS = 2 * Math.PI / 60 * minute
      this.ctx.rotate(rad)
      this.ctx.lineWidth = 3 * this.rem
      this.ctx.lineCap = 'round'
      this.ctx.moveTo(0, 10 * this.rem)
      this.ctx.lineTo(0, -this.radius + 50 * this.rem)
      this.ctx.stroke()
      this.ctx.restore()
    },
    //秒针
    drawSecond (second) {
      this.ctx.save()
      this.ctx.beginPath();
      this.ctx.fillStyle = 'red'
      const rad = 2 * Math.PI / 60 * second
      this.ctx.rotate(rad)
      this.ctx.moveTo(-2, 20 * this.rem)
      this.ctx.lineTo(2, 20 * this.rem)
      this.ctx.lineTo(1, -this.radius + 38 * this.rem)
      this.ctx.lineTo(-1, -this.radius + 38 * this.rem)
      this.ctx.fill()
      this.ctx.restore()
    },
    //原点
    drawOrigin () {
      this.ctx.beginPath();
      this.ctx.fillStyle = '#fff'
      this.ctx.arc(0, 0, 3 * this.rem, 0, 2 * Math.PI, false)
      this.ctx.fill()
    },
    //初始化
    init () {
      this.dom = document.getElementById('clock');
      this.ctx = this.dom.getContext('2d');
      this.width = this.ctx.canvas.width
      this.height = this.ctx.canvas.height
      this.radius = this.width / 2
      this.rem = this.width / 200
    },
    //获取时间并定时调用
    handleDraw () {
      this.ctx.clearRect(0, 0, this.width, this.height)
      const time = new Date();
      const hour = time.getHours();
      const minute = time.getMinutes();
      const second = time.getSeconds();
      this.drawBackground()
      this.drawHour(hour, minute)
      this.drawMinute(minute)
      this.drawSecond(second)
      this.drawOrigin()
      this.ctx.restore()
    }
  },
  created () { },
  mounted () {
    this.init()
    this.handleDraw()
    setInterval(this.handleDraw, 1000)
  }
}
</script>
<style lang="scss" scoped>
@import "~@/assets/css/scss/common";
.Test_page {
  @include flx-dsp($drt: row, $jsc: center, $ali: center);
  background-color: #999;
}
</style>