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