【案例】canvas之时钟

667 阅读1分钟

实现样式

shizhong.gif

实现代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    canvas{
      border: 1px solid #000;
    }
  </style>
</head>
<body>
  <canvas id="myCanvas" width="800" height="600"></canvas>
  <script>
    let canvas = document.getElementById('myCanvas')
    let ctx = canvas.getContext('2d')
    let w = canvas.width, h =  canvas.height
    let time = [3,4,5,6,7,8,9,10,11,12,1,2]

    
    function createWatch(){
      let r = 150 , x = w/2 ,y= h/2
      ctx.beginPath()
      ctx.arc(x, y,r,0,Math.PI * 2,true)
      ctx.stroke()
      ctx.closePath()
      for(let i=0 ;i<time.length ;i++){
        let angle = 30 * i * Math.PI > 0 ?  30 * i * Math.PI / 180 : 0
        let dx = time[i] < 6 ? 10 : time[i] != 12 && time[i] != 6 ?  -10: 0
        let dy = angle > Math.PI ? -10 :  angle!= Math.PI && angle!= 0 ? 10 :0
        ctx.fillText(time[i],x + r * Math.cos(angle) + dx,y + r * Math.sin(angle)+ dy )
      }
      // 画针
      createLine(x,y)
      // 画个点
      ctx.beginPath()
      ctx.arc(x, y,5,0,Math.PI * 2,true)
      ctx.fill()
      ctx.closePath()
    }
    // 时针/ 分针 / 秒针
    function createLine(x,y){
      let time =  new Date()
      let hour = time.getHours(), minutes = time.getMinutes(), second = time.getSeconds()
      console.log(hour,minutes,second)
      // 画时针 - 绿色 - 5
      ctx.lineCap = 'round'
      createNeedle(80,'green',5,hour,'hour',x,y)
      // 画分针 - 蓝色 - 3
      createNeedle(90,'blue',3,minutes,'minutes',x,y)
      // 画秒针 - 红色 - 2
      createNeedle(100,'red',2,second,'second',x,y)
    }

    function createNeedle(r,color,lineWidth,date,type,x,y){ //(x,y)时圆心的坐标
      ctx.save()
      ctx.beginPath()
      ctx.strokeStyle = color
      ctx.lineWidth = lineWidth
      ctx.moveTo(x,y)
      angle = getRadian(date,type)
      ctx.lineTo( x + r * Math.cos(angle), y +r * Math.sin(angle))
      ctx.stroke()
      ctx.closePath()
      ctx.restore()
    }

    // 获取弧度
    function getRadian(date, type){
      switch(type){
        case 'hour':
          date = date % 12 == 0 ?  12 : date % 12
          return 30 * time.indexOf(date) * Math.PI > 0 ?  30 * time.indexOf(date) * Math.PI / 180 : 0
        case 'minutes':
          return date > 15 ? (date - 15) * 6 * Math.PI / 180 : date!= 15 ? (270 + date * 6 ) *Math.PI / 180: 0
          break
        case 'second':
          return date > 15 ? (date - 15) * 6 * Math.PI / 180 : date!= 15 ? (270 + date * 6 ) *Math.PI / 180: 0
          break
      }
    }

    function move(){
      window.requestAnimationFrame(move)
      ctx.clearRect(0,0,w,h)
      createWatch()
    }
    move()
  </script>
</body>
</html>

步骤:

  • 绘制钟表
    • 圆和文字的绘制,其中文字的绘制主要是通过将数字位置和弧度进行对应绘制而来
  • 绘制指针
    • 绘制时针、分针、秒针。也主要是利用不同时间对应的不同的弧度来在页面上实现的
let dx = time[i] < 6 ? 10 : time[i] != 12 && time[i] != 6 ?  -10: 0
let dy = angle > Math.PI ? -10 :  angle!= Math.PI && angle!= 0 ? 10 :0
  • 代码中这部分的代码主要是为了让圆上的数字可以友好的显示