Search code examples
javascriptcanvaspie-chartpi

Canvas animating a pie chart


I'm trying to animate a pie chart without using any plugins. With below code I can get pretty close to it, but not quite. There are gaps between each segments because the incremental value is set to ++. Can anyone suggest a clean solution to my problem? Here's my 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)

Solution

  • Here is a demo. You were really close. You just need to update your sAngle apropriately and your 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);
        }
    }
    

    Seems I can get it to render better. Working on it.

    EDIT: Better render here

    EDIT: Best render here