Canvas實(shí)現(xiàn)進(jìn)度圈

import React, { useEffect } from 'react'

import './index.less'

const ProgressCircleDemo: any = (props: any) => {
    const { clientWidth = 1 } = document.querySelector('html') || {}
    console.log('=====', clientWidth)
    const calcCssFn = (num: any) => {
        return (clientWidth * num) / 750
    }
    const {
        children,
        percent,
        clockwise,
        trackColor = '#ffe7d8',
        fillStartColor = '#ff873d',
        size = 120,
        lineNum = 10,
        keys = 0,
    } = props || {}
    const width = calcCssFn(size) / 2
    const height = width
    const lineWidth = calcCssFn(lineNum)
    const radius = width - lineWidth / 1.5
    const progress = percent
    useEffect(() => {
        setTimeout(() => {
            const canvas: any = document.querySelector('#myCanvas' + keys)
            if (canvas) {
                const ctx = canvas.getContext('2d')
                const size = Math.min(canvas.width, canvas.height)
                // 解決 canvas 繪制毛邊問題
                const sizePX = `${size}px`
                canvas.style.width = sizePX
                canvas.style.height = sizePX
                canvas.height = size * window.devicePixelRatio
                canvas.width = size * window.devicePixelRatio
                ctx.scale(window.devicePixelRatio, window.devicePixelRatio)

                ctx.beginPath()
                // arc(定義一個中心點(diǎn),半徑,起始角度,結(jié)束角度,和繪圖方向:順時針或逆時針)
                ctx.arc(width, height, radius, 0, Math.PI * 2)
                ctx.lineWidth = lineWidth
                ctx.lineCap = 'round'
                ctx.strokeStyle = trackColor

                ctx.stroke()
                ctx.closePath()
                // 繪制進(jìn)度條數(shù)據(jù)為0不渲染
                if (progress) {
                    const startAngle = 0 || (3 / 2) * Math.PI
                    const percentage = progress
                    const diffAngle = (percentage / 100) * Math.PI * 2
                    ctx.beginPath()
                    ctx.arc(
                        width,
                        height,
                        radius,
                        startAngle,
                        diffAngle + startAngle,
                        clockwise < 0 ? true : false
                    )

                    ctx.strokeStyle = fillStartColor
                    ctx.stroke()
                    ctx.closePath()
                }

                // ctx.beginPath()
                // ctx.fillStyle = '#000'
                // ctx.textAlign = 'center'
                // ctx.font = '16px serif'
                // ctx.fillText(percentage + '%', width + 2, height + 5)
            }
        }, 100)
    })
    return (
        <div className="div-wrap">
            <canvas
                id={'myCanvas' + keys}
                width={width * 2}
                height={width * 2}
            ></canvas>
            <div className="progress-content">{children}</div>
        </div>
    )
}
export default ProgressCircleDemo

.div-wrap {
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    .progress-content {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
    }
}

<DemoCircle
    percent={25}
    keys={'onlyKey'}
    clockwise={clockwise'? 1 : -1}
>
    25%                     
</DemoCircle>
進(jìn)度圈.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容