html5 canvas 环形图(百分比转换为角度及弧度)

486 阅读1分钟

cc.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<canvas id="canvas" width="500" height="500" style="background: #0A2557"></canvas>
<script>
    let canvas = document.querySelector('#canvas');
    let ctx = canvas.getContext('2d');
    let num = 1;
    let x = canvas.width / 2;
    let y = canvas.height / 2;
    let arrNum = [500,100, 3000];
    let arrNumLen = arrNum.length;
    let arrColor = ['red', '#4CDFFF', '#FF8E66', '#3170F1'];
    let count = 0;
    let radianStart = 0;

    count = arrNum.reduce((num1, num2) => {
        return num1 + num2
    });


    function f() {
        // 外圈
        for (let i = 0; i < arrNumLen; i++) {
            // arrNum[i] / count = 百分比
            // arrNum[i] / count * 360 = 角度
            // 角度 * Math.PI / 180 = 弧度
            let radianEnd = (arrNum[i] / count * 360) * Math.PI / 180;
            if (radianEnd !== 0) {
                ctx.save();
                ctx.beginPath();
                ctx.translate(x, y);
                ctx.shadowBlur = 15;
                ctx.shadowColor = arrColor[i];
                ctx.strokeStyle = arrColor[i];
                ctx.lineWidth = 10;
                // radianStart 起始弧度
                // radianEnd + radianStart 结束弧度
                // +interval 间隔
                ctx.arc(0, 0, 108, radianStart, radianEnd + radianStart);
                ctx.stroke();
                ctx.restore();
                radianStart += radianEnd;  // 弧度累加
            }
        }

        // 内圈
        ctx.save();
        ctx.beginPath();
        ctx.shadowBlur = 10;
        ctx.shadowColor = "#01AEE5";
        ctx.fillStyle = '#0C1B4E';
        ctx.arc(x, y, 80, 0, Math.PI * 2);
        ctx.fill();
        ctx.restore();

        // 总计数字
        ctx.beginPath();
        ctx.font = "25px Arial";
        ctx.textAlign = "center";
        ctx.fillStyle = '#ffffff';
        ctx.fillText(count, x, y - 15);

        // 横线
        ctx.save();
        ctx.beginPath();
        ctx.ellipse(x, y, 50, 1, 0, 0, Math.PI * 2);
        let grd = ctx.createRadialGradient(x, y, 50, x, y, 1);
        grd.addColorStop(0, "rgba(1,174,229,0)");
        grd.addColorStop(1, "rgba(1,174,229,1)");
        ctx.fillStyle = grd;
        ctx.fill();
        ctx.restore()

        ctx.font = "20px Arial";
        ctx.textAlign = "center";
        ctx.fillStyle = '#ffffff';
        ctx.fillText('报警总数', x, y + 30);

        // 旋转部分
        ctx.save();
        ctx.translate(x, y);
        ctx.beginPath();
        ctx.rotate(num * Math.PI / 180);
        ctx.lineWidth = 2;
        ctx.arc(0, 0, 82, 0, Math.PI);
        let grd1 = ctx.createRadialGradient(0, 50, 80, 0, 80, 20);
        grd1.addColorStop(0, "rgba(1,174,229,0.0)");
        grd1.addColorStop(1, "rgba(1,174,229,1)");
        ctx.strokeStyle = grd1;
        // ctx.fillStyle = grd1;
        ctx.stroke();
        // ctx.fill();
        ctx.beginPath();
        ctx.lineWidth = 2;
        ctx.arc(0, 0, 82, Math.PI, Math.PI * 2);
        let grd2 = ctx.createRadialGradient(0, -50, 80, 0, -80, 20);
        grd2.addColorStop(0, "rgba(1,174,229,0)");
        grd2.addColorStop(1, "rgba(1,174,229,1)");
        ctx.strokeStyle = grd2;
        // ctx.fillStyle = grd2;
        ctx.stroke();
        // ctx.fill();
        ctx.restore();
        num++;
    }


    (function drawFrame() {
        window.requestAnimationFrame(drawFrame);
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        f()
    })();
    // f()
</script>
</body>
</html>