Search code examples
htmlcanvasgeometryanimated

Animate a Fill Circle using Canvas


Basically I want to be able to Fill a Circle using canvas, but it animate to a certain percentage. I.e only have the circle fill up 80% of the way.

My canvas knowledge isn't amazing, Here is an image i made in photoshop to display what i want.

AnimateSequence

I want the circle to start empty and then Fill up to say 70% of the circle. Is this possible with Canvas, if so? can anyone shed some light on how to do it?

Here is a fiddle of what I've managed

http://jsfiddle.net/6Vm67/

 var canvas = document.getElementById('Circle');
 var context = canvas.getContext('2d');
 var centerX = canvas.width / 2;
 var centerY = canvas.height / 2;
 var radius = 80;

 context.beginPath();
 context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
 context.fillStyle = '#13a8a4';
 context.fill();
 context.lineWidth = 10;
 context.strokeStyle = '#ffffff';
 context.stroke();

Any help would be massively appreciated


Solution

  • Clipping regions make this very easy. All you have to do is make a circular clipping region and then fill a rectangle of some size to get a "partial circle" worth of fill. Here's an example:

    var canvas = document.getElementById('Circle');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 80;
    
    var full = radius*2;
    var amount = 0;
    var amountToIncrease = 10;
    
    function draw() {
        context.save();
        context.beginPath();
        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
        context.clip(); // Make a clipping region out of this path
        // instead of filling the arc, we fill a variable-sized rectangle
        // that is clipped to the arc
        context.fillStyle = '#13a8a4';
        // We want the rectangle to get progressively taller starting from the bottom
        // There are two ways to do this:
        // 1. Change the Y value and height every time
        // 2. Using a negative height
        // I'm lazy, so we're going with 2
        context.fillRect(centerX - radius, centerY + radius, radius * 2, -amount);
        context.restore(); // reset clipping region
    
        context.beginPath();
        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
        context.lineWidth = 10;
        context.strokeStyle = '#000000';
        context.stroke();
    
        // Every time, raise amount by some value:
        amount += amountToIncrease;
        if (amount > full) amount = 0; // restart
    }
    
    draw();
    // Every second we'll fill more;
    setInterval(draw, 1000);
    

    http://jsfiddle.net/simonsarris/pby9r/