美文网首页
Canvas 绘制渐进式圆头圆环图

Canvas 绘制渐进式圆头圆环图

作者: markRao | 来源:发表于2024-04-08 15:43 被阅读0次
    移动端 native 效果图
    当前项目大量 Web 需求,目前需要将 native 的效果同步到 Web,一顿百度各种图表库,F2·移动端可视化引擎 | AntV (antgroup.com)
    Apache ECharts
    一顿百度,发现添加圆头很麻烦,也没找到如何解决,最后只能用 canvas 自己来绘制了
    Tab-环形图 (online-video-cutter.com).gif

    具体实现代码如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>环形图</title>
        <style>
            canvas {
                border: 1px solid pink;
            }
        </style>
    </head>
    
    <body>
        <canvas width="400" height="500"></canvas>
        <script type="text/javascript">
            const canvas = document.querySelector('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);
            // 2秒动画
            const duration = 2000; 
            let startTime = null;
            const lineWidth = 20;
            ctx.lineWidth = lineWidth;
            // 设置线条末端为圆头效果
            ctx.lineCap = 'round'; 
            const data = [{
                "value": 100,
                "color": "red"
            }, {
                "value": 50,
                "color": "blue"
            }, {
                "value": 15,
                "color": "green"
            }, {
                "value": 20,
                "color": "#ccc"
            }];
            const sum = 185;
            //设置角度的中间变量
            const x0 = size / 2;
            const y0 = x0;
            const radius = (size - lineWidth) / 2;
            console.log(`size=${size} y0=${y0} radius=${radius} lineWidth=${lineWidth}`)
            const mathPI = Math.PI / 180
            function draw(progress) {
                // 从-90度开始绘制
                let tempAngle = -90;
                const currAngle = 360 * progress
                for (let i = 0; i < data.length; i++) {
                    //因为设置不同的颜色,所以每次绘制完起一个新状态
                    ctx.beginPath();
                    //当前扇形的角度
                    const angle = data[i].value / sum * currAngle;
                    ctx.strokeStyle = data[i].color;
                    //开始从 tempAngle 绘制
                    const startAngle = tempAngle * mathPI;
                    //从tempAngle 绘制到 我们自己的angle区域
                    const endAngle = (tempAngle + angle) * mathPI;
                    //x0,y0 圆心坐标,radius:半径,startAngle:开始绘制的弧度,endAngle:结束绘制的弧度
                    ctx.arc(x0, y0, radius, startAngle, endAngle);
                    ctx.stroke();
                    tempAngle += angle; //下一次绘制的起始角度
                }
            }
            function animate(timestamp) {
                if (!startTime) startTime = timestamp;
                let progress = (timestamp - startTime) / duration;
                if (progress > 1) progress = 1;
                draw(progress);
                if (progress < 1) {
                    requestAnimationFrame(animate);
                }
            }
            requestAnimationFrame(animate);
        </script>
    </body>
    
    </html>
    

    相关文章

      网友评论

          本文标题:Canvas 绘制渐进式圆头圆环图

          本文链接:https://www.haomeiwen.com/subject/lwlxxjtx.html