The desired effect

html

<canvas id="circle-count" type="2d"></canvas>
Copy the code

Style style

#circle-count
    width 120rpx
    height 120rpx
Copy the code

Logic code

Initialization method:

initProgress() { const query = uni.createSelectorQuery() query.select("#circle-count").fields({ node: true, size: True}).exec((res) => {canvas = res[0].node CTX = res[0].node.getContext("2d") // Get device pixel for Retina screen than const DPR = Uni.getsysteminfosync ().pixelratio // enlarging the pixels of canvas canvas according to the device pixelRatio, Canvas. width = toRpx(120) * DPR Canvas. height = toRpx(120) * DPR // Scale ctx.scale(DPR, Ctx.fillstyle = "#FF6951" // Set the filling color ctx.lineWidth = toRpx(8) // Set the width of the ring Arc (toRpx(60), toRpx(60), toRpx(56), startAngle, EndAngle) ctx.fill() // Fill the current path ctx.stroke() // Stroke the current path // Draw the middle rectangle drawRoundRect(CTX, toRpx(36), toRpx(36), "#ffffff", toRpx(48), toRpx(48), toRpx(8) ) }) }Copy the code

It should be noted that the size value can not be written dead, because canvas style is RPX responsive unit, and it is also dynamically calculated according toRpx calculation method, toRpx method is as follows:

Export function toRpx(val) {const res = uni.getSystemInfosync () const scaleRate = res.windowWidth / 375 return val * scaleRate }Copy the code
/** * @description: Draw rounded rectangle * @param {CTX} CTX * @Param {number} x coordinate * @param {number} y coordinate * @return {bg} background color * @return {h} Height of rectangle * @return Export function drawRoundRect(CTX, x, y, bg, h, w) Radius) {ctx.beginPath() ctx.fillstyle = bg // top left ctx.arc(x + radius, y + radius, radius, math.pi, Math.PI * 3/2) ctx.lineTo(x + W-radius, y) // Upper right ctx.arc(x + W-radius, y + RADIUS, radius, math. PI * 3/2, Arc (x + w-radius, y + h-radius, radius, 0) ctx.arc(x + w-radius, y + h-radius, radius, 0) CTX. Math.pi / 2) ctx.lineTo(x + radius, y + h) // lower left ctx.arc(x + radius, y + h-radius, radius, math.pi / 2, Math.PI) ctx.lineTo(x, y + radius) ctx.fill() }Copy the code
Const end = startAngle + (endAngle / 60) * (60-this.time) ctx.beginPath() // Start a new path ctx.lineWidth StrokeStyle = "#FFD957" // Set the ring color ctx.lineCap = "round" // Set the ring end shape ctx.arc(toRpx(60), ToRpx (60), toRpx(56), startAngle, end, false) ctx.stroke() // Stroke current path}Copy the code
// Countdown timer, HandleCountTime () {timer = setInterval(() => {this.time -= 0.1 this.render() if (time < 0) {// The time is up clearInterval(timer) } }, 100) }Copy the code

Finally, you can follow my official account to get blog updates in time