Canvas 动画饼图

Canvas animating a pie chart

我正在尝试在不使用任何插件的情况下制作饼图动画。使用下面的代码,我可以非常接近它,但不完全是。由于增量值设置为++,因此每个段之间存在间隙。谁能为我的问题提出一个干净的解决方案?这是我的 code

            var canv2 = document.getElementById("canvas2");
            var ctx2 = canv2.getContext("2d");
            var r = 60, sAngle = 0, angle = 0, eAngle = 0;
            var interval2 = setInterval(function() {

                if (angle == 0) {
                    ctx2.beginPath();
                    sAngle = 0;
                } else if (angle == 90) {
                    ctx2.beginPath();
                    sAngle = Math.PI*0.5;
                } else if (angle == 180) {
                    ctx2.beginPath();
                    sAngle = Math.PI;
                } else if (angle == 270) {
                    ctx2.beginPath();
                    sAngle = Math.PI*1.5;
                } else if (angle == 360) {
                    ctx2.beginPath();
                    sAngle = Math.PI*2;
                } else {
                    if (angle > 0 && angle < 90) {
                        ctx2.arc(200, 80, r, sAngle, eAngle);
                        ctx2.lineTo(200, 80);
                        ctx2.fillStyle = "red";
                        ctx2.fill();
                    } else if (angle > 90 && angle < 180) {
                        ctx2.arc(200, 80, r, sAngle, eAngle);
                        ctx2.lineTo(200, 80);
                        ctx2.fillStyle = "green";
                        ctx2.fill();
                    } else if (angle > 180 && angle < 270) {
                        ctx2.arc(200, 80, r, sAngle, eAngle);
                        ctx2.lineTo(200, 80);
                        ctx2.fillStyle = "orange";
                        ctx2.fill();
                    } else if (angle > 270 && angle < 360) {
                        ctx2.arc(200, 80, r, sAngle, eAngle);
                        ctx2.lineTo(200, 80);
                        ctx2.fillStyle = "blue";
                        ctx2.fill();
                    } else {
                        clearInterval(interval2);
                    }
                }

                angle++;
                eAngle = angle*Math.PI/180;

        }, 10)

Here 是一个演示。你真的很亲密。你只需要适当地更新你的sAngle和你的eAngle。

if (angle == 0) {
    ctx2.beginPath();
    sAngle = -0.001;
} else if (angle == 90) {
    ctx2.beginPath();
    sAngle = Math.PI * 0.501;
} else if (angle == 180) {
    ctx2.beginPath();
    sAngle = Math.PI-.001;
} else if (angle == 270) {
    ctx2.beginPath();
    sAngle = Math.PI * 1.501;
} else if (angle == 360) {
    ctx2.beginPath();
    sAngle = Math.PI * 1.999;
} else {
    if (angle > 0 && angle < 90) {
        ctx2.arc(200, 80, r, sAngle, eAngle+.02);
        ctx2.lineTo(200, 80);
        ctx2.fillStyle = "red";
        ctx2.fill();
    } else if (angle > 90 && angle < 180) {
        ctx2.arc(200, 80, r, sAngle, eAngle+.02);
        ctx2.lineTo(200, 80);
        ctx2.fillStyle = "green";
        ctx2.fill();
    } else if (angle > 180 && angle < 270) {
        ctx2.arc(200, 80, r, sAngle, eAngle+.02);
        ctx2.lineTo(200, 80);
        ctx2.fillStyle = "orange";
        ctx2.fill();
    } else if (angle > 270 && angle < 360) {
        ctx2.arc(200, 80, r, sAngle, eAngle+.02);
        ctx2.lineTo(200, 80);
        ctx2.fillStyle = "blue";
        ctx2.fill();
    } else {
        clearInterval(interval2);
    }
}

看来我可以让它渲染得更好。正在努力。

编辑:Better render here

编辑:Best render here

我建议你使用 requestAnimationFrame 而不是 setinterval。 这是一个颜色数量可变的示例: https://jsfiddle.net/y38q271f/4/

var canv2 = document.getElementById("canvas2");
var ctx2 = canv2.getContext("2d");

var r = 60,
sAngle = 0,
angle = 0,
eAngle = 0;

var tourTime = 3;
var speed = 360 / (tourTime * 1000);  // degrees per millisecond.
var initTime = 0;
var colors = ['#0f0', '#1f0', '#2f0', '#3f0', '#4f0', '#5f0', '#6f0', '#7f0',
              '#8f0', '#9f0', '#af0', '#bf0', '#cf0', '#df0', '#ef0', '#ff0',
              '#fe0', '#fd0', '#fc0', '#fb0', '#fa0', '#f90', '#f80', '#f70',
              '#f60', '#f50', '#f40', '#f30', '#f20', '#f10', '#f00'];

function anim(time) {
    if (initTime == 0) initTime = time;
    time -= initTime;
    var ang = (time * speed) % 360;
    var n = colors.length;
    var i, angS, angE, color;
    for (i = 0 ; i < colors.length ; i++) {
        color = colors[i];
        angS = i * 360 / n;
        if (angS > ang) break;
        angE = Math.min((i + 1) * 360 / n, ang);
        ctx2.beginPath();
        ctx2.arc(200, 80, r, Math.PI * angS / 180, Math.PI * angE / 180);
        ctx2.lineTo(200, 80);
        ctx2.closePath();
        ctx2.fillStyle = color;
        ctx2.fill();
    };
    window.requestAnimationFrame(anim);
}

window.requestAnimationFrame(anim);