Calculation formula of center coordinates

    x1   =   x0   +   r   *   cos( a )
    y1   =   y0   +   r   *   sin( a )

According to the formula, x0 and y0 are the coordinates of the center of the circle, and x1 and y1 are the real coordinates

Analyze the clock

  • The circle is divided into 12 parts and each part is an hour.
  • A circle is divided into 60 minutes and a scale is one minute (minute hand)
  • Seconds are measured using getMilliseconds, 1000ms is 1 second, and the circumference is divided into 60 milliseconds each

Basis of preparation

     let height = 500  / / canvas width is high
     let width = 500
     let distance = 10 // The minute-second scale length
     let distance1 = 15 // The length of the clockwise scale
     
     let x0 = 0  // Default initial center position
     let y0 = 0
     function calcPoint(r, a) {
        x1   =   x0   +   r   *   Math.cos( a )
        y1   =   y0   +   r   *   Math.sin( a )
        return [x1, y1]
      }

Copy the code

The canvas to prepare


 let Timer = function(props) {
         // Create a DOM node reference
        let ref = React.createRef()
        useEffect(() = > {
            let canva = ref.current
            // Canvas has some jagged issues when setting width and height from CSS
            canva.width = width
            canva.height = height
            let ctx = canva.getContext('2d')
          
            drawWatch(ctx, width,height)
            return () = > stop = false}, [])return h('canvas',  {className: 'basic_class', ref})
    }
  // Render clock
 ReactDOM.render(h(Timer), document.getElementById('app'));    
Copy the code

Drawing process

  let reqFrame = requestAnimationFrame || setTimeout
  let stop = false // Used to end the reqFrame when the component is destroyed
  function drawWatch(ctx, width,height) {
        if(! stop) { reqFrame(drawWatch.bind(null, ctx, width,height))
        }
        ctx.clearRect(0.0,width, height)
        chart.drawTick(ctx)
        chart.drawText(ctx)
        chart.drawLine(ctx)
  }
  
  
   let chart = {
          drawTick(ctx) {
            let outerline = height*0.8/2
            let centerPoint = [width/2, height/2]
            let maxDeg = 2*Math.PI
            let tick = maxDeg/60
            x0 = centerPoint[0]
            y0 = centerPoint[1]

            ctx.beginPath()
            ctx.lineCap="round"
            for(let item = 0; item<60; item++) {
              let deg = tick*item
              let innerline = outerline - distance
              ctx.strokeStyle = '#aaa'
              if(item%5= =0) {
                innerline = outerline - distance1
                ctx.strokeStyle = '#fff'
              }
              // Use the center coordinates method to calculate
              Ctx.save () ctx.rotate() ctx.restore()
              let start = calcPoint(innerline, deg)
              letend = calcPoint(outerline, deg) ctx.moveTo(... start) ctx.lineTo(... end) } ctx.stroke() },drawText(ctx) {
            let maxDeg = 2*Math.PI
            let tick = maxDeg/ 12
            let outerline = height*0.8/2
            let x = -3
            let y = - outerline  +  distance1 + 15
            ctx.beginPath()
            // grd.addColorStop(0,"#FF0000");
            // grd.addColorStop(1,"#00FF00");
            ctx.fillStyle='#fff';
            for(let item = 0; item < 12; item++) {
              ctx.save()
              let num = item
              let x1 = x 
              if(item == 0) { num = 12}
              if(num > 9)  { x1 = -6 }
              ctx.translate(width/2, height/2)
              ctx.rotate(tick*item)
              ctx.strokeStyle = '#fff'
              ctx.fillText(num, x1, y)
              ctx.restore()
            }

            ctx.stroke()
          },
          drawLine(ctx) {
            let outerline = height*0.8/2
            let date = new Date(a)let times = date.getMilliseconds()
            let second = date.getSeconds()
            let hour =date.getHours()
            let mins =date.getMinutes()
            let secondDeg = 2*Math.PI/60
            let hourDeg = 2*Math.PI/12
            // Hour added minute hand progress to make the hour hand point more reasonable position
            let hDeg = (hour + mins/60) * hourDeg  +   - Math.PI/2 
            // The span of the minute hand is relatively small
            let mDeg = mins * secondDeg - Math.PI/2
            // The Angle to turn the second hand
            let sDeg = (second + times/1000) * secondDeg - Math.PI/2
            
            let hp = calcPoint(outerline - distance - 100,  hDeg )
            let mp = calcPoint(outerline - distance -30,  mDeg )
            let sp = calcPoint(outerline - distance,  sDeg ) 
            
            ctx.beginPath()
            ctx.moveTo(width/2, height/2) ctx.lineTo(... mp) ctx.strokeStyle ='#fff'
            ctx.stroke()

            ctx.beginPath()
            ctx.moveTo(width/2, height/2) ctx.lineTo(... hp) ctx.strokeStyle ='#19f'
            ctx.stroke()
            
            ctx.beginPath()
            ctx.moveTo(width/2, height/2) ctx.lineTo(... sp) ctx.strokeStyle ='#f91'
            ctx.stroke()
          }
      }

Copy the code

The effect

The end of the

There is no complicated process for the realization of this function, which is relatively basic knowledge. Writing this article can be considered as a deeper understanding of Canvas