canvas 饼图动效

完成效果以下: css

动效饼图显示

1、绘制静态饼图

step1 设置圆心坐标,半径进行绘制大圆和小圆

甜甜圈🍩显示
html

<canvas id="myCanvas" width="600" height="600"></canvas>
复制代码

csshtml

canvas {
    border: 1px solid #ccc;
}
复制代码

jscanvas

var canvas = document.getElementById("myCanvas");
var context = canvas.getContext('2d');
var cX = canvas.width / 2; //圆心X坐标
var cY = canvas.height / 2; //圆心Y坐标
var bR = 200; //设置大圆半径
var sR = 100; //设置小圆半径

// step1 建立大圆
context.beginPath();
context.arc(cX, cY, bR, 0, 2 * Math.PI);
context.fillStyle = 'red';
context.fill();

// step2 建立小圆
context.beginPath();
context.arc(cX, cY, sR, 0, 2 * Math.PI);
context.fillStyle = 'white';
context.fill();
复制代码

step2 绘制45°扇形

45°扇形显示

// step1 建立大圆
context.beginPath();
context.moveTo(cX, cY);
context.lineTo(cX + bR, cY); 
context.arc(cX, cY, bR, 0, 1 / 8 * 2 * Math.PI); //绘制45°圆
context.lineTo(cX, cY);
context.fillStyle = 'red';
context.fill();

// step2 建立小圆
context.beginPath();
context.moveTo(cX, cY);
context.lineTo(cX + sR, cY);
context.arc(cX, cY, sR, 0, 1 / 8 * 2 * Math.PI); //绘制45°圆
context.lineTo(cX, cY);
context.fillStyle = 'white';
context.fill();
复制代码

以上代码存在个问题(js小数点的问题),以下图,小圆未把大圆区域所有填充彻底,边缘存在红色虚线 bash

45°扇形显示
解决办法以下:对小圆区域进行描边

context.strokeStyle = "white";
context.stroke();
context.lineWidth = 2;
复制代码

step3 把大圆、小圆的代码进行封装,目的为了建立多个不一样弧度的扇形时方便调用

function drawDonuts(startAngle, endAngle, color) {

    // step1 建立大圆
    context.beginPath();
    context.moveTo(cX, cY);
    context.lineTo(cX + bR * Math.cos(startAngle), cY + bR * Math.sin(startAngle));
    context.arc(cX, cY, bR, startAngle, endAngle);
    context.lineTo(cX, cY);
    context.fillStyle = color;
    context.fill();

    // step2 建立小圆
    context.beginPath();
    context.moveTo(cX, cY);
    context.lineTo(cX + sR * Math.cos(startAngle), cY + sR * Math.sin(startAngle));
    context.arc(cX, cY, sR, startAngle, endAngle);
    context.lineTo(cX, cY);
    context.fillStyle = 'pink';
    context.fill();
    // 添加如下代码是为 解决小圆未把大圆区域所有填充彻底的问题,如上图所示边缘存在红色虚线
    context.strokeStyle = "pink";
    context.stroke();
    context.lineWidth = 2;

    }
复制代码
// 设置每一个扇形的弧度比例以及颜色
var setArr = [{
    scale: 0.2 * 2 * Math.PI,
    color: "red"
}, {
    scale: 0.35 * 2 * Math.PI,
    color: "cyan"
}, {
    scale: 0.25 * 2 * Math.PI,
    color: "purple"
}, {
    scale: 0.1 * 2 * Math.PI,
    color: "blue"
}, {
    scale: 0.1 * 2 * Math.PI,
    color: "orange"
}];

var startAngle = 0;
var endAngle = 0;
for(var i =0;i<setArr.length;i++){
    endAngle += setArr[i].scale;
    drawDonuts(startAngle,endAngle,setArr[i].color); //调用封装函数
    startAngle = endAngle;
}
复制代码

2、动态实现

step1 实现纯色甜甜圈动画显示

纯色圆动效显示

注释该段代码
// for(var i =0;i<setArr.length;i++){
//     endAngle += setArr[i].scale;
//     drawDonuts(startAngle,endAngle,setArr[i].color);
//     startAngle = endAngle;
// }

var speed = 5 / 360 * 2 * Math.PI; //控制动态显示的速度
var timer1 = setInterval(function() {
    if (endAngle > 2 * Math.PI) {
        clearInterval(timer1); //优化性能,再也不继续渲染
    }
    endAngle += speed;
    drawDonuts(startAngle, endAngle, 'cyan');
    startAngle = endAngle;
}, 1000 / 40);
复制代码

step2 实现不一样颜色甜甜圈动效显示

var speed = 5 / 360 * 2 * Math.PI; //控制动态显示的速度
var dataArr = [0];
var sum = 0;

for (var i = 0; i < setArr.length; i++) {
    sum += setArr[i].scale;
    dataArr.push(sum);
}
var timer1 = setInterval(function() {
    endAngle += speed;
    if (endAngle > 2 * Math.PI) {
        clearInterval(timer1); //优化性能,再也不继续渲染
    }
    for (var i = 1; i < dataArr.length; i++) {
        if (endAngle >= dataArr[i - 1] && endAngle <= dataArr[i]){
            drawDonuts(startAngle, endAngle, setArr[i - 1].color);
            break;
        }
    }
    startAngle = endAngle - 0.01; //处理动效旋转时出现的间隙问题
}, 1000 / 40);
复制代码

大功告成 —— ending

太少写文章,表达不大好,欢迎你们提宝贵意见~感激~函数

相关文章
相关标签/搜索