Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 467
BigOrinj Avatar asked May 31 '13 16:05

BigOrinj


People also ask

How do you fill a circle in canvas?

Description. To draw a circle with HTML5 Canvas, we can create a full arc using the arc() method by defining the starting angle as 0 and the ending angle as 2 * PI.

Can you animate on canvas?

You can create animations with HTML5 by combining HTML, CSS, and JavaScript (JS), with which you can build shapes. Also, you can control animations and edit images, video, and audio by means of JS or CSS elements, all of which you then add to a drawing board, which you set up with the <canvas> element.

How do I animate an image in canvas?

To animate with canvas you need to record the location of your object and then increment it on a new frame setInterval(draw, 1000 / 25); allows you to run a function after a specified time interval. You could use this function to update the position of your object on the page each time a new frame is rendered.


2 Answers

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/

like image 193
Simon Sarris Avatar answered Sep 18 '22 14:09

Simon Sarris


This is a little more dynamic, object-oriented version, so you can configure the options as the circle radius, border width, colors, duration and step of animation, you can also animate the circle to a certain percentage. It was quite fun to write this.

<canvas id="Circle" width="300" height="300"></canvas>
<script>
    function Animation( opt ) {
        var context = opt.canvas.getContext("2d");
        var handle = 0;
        var current = 0;
        var percent = 0;

        this.start = function( percentage ) {
            percent = percentage;
            // start the interval
            handle = setInterval( draw, opt.interval );
        }

        // fill the background color
        context.fillStyle = opt.backcolor;
        context.fillRect( 0, 0, opt.width, opt.height );

        // draw a circle
        context.arc( opt.width / 2, opt.height / 2, opt.radius, 0, 2 * Math.PI, false );
        context.lineWidth = opt.linewidth;
        context.strokeStyle = opt.circlecolor;
        context.stroke();

        function draw() {
            // make a circular clipping region
            context.beginPath();
            context.arc( opt.width / 2, opt.height / 2, opt.radius-(opt.linewidth/2), 0, 2 * Math.PI, false );
            context.clip();

            // draw the current rectangle
            var height = ((100-current)*opt.radius*2)/100 + (opt.height-(opt.radius*2))/2;
            context.fillStyle = opt.fillcolor;
            context.fillRect( 0, height, opt.width, opt.radius*2 );

            // clear the interval when the animation is over
            if ( current < percent ) current+=opt.step;
            else clearInterval(handle);
        }
    }

    // create the new object, add options, and start the animation with desired percentage
    var canvas = document.getElementById("Circle");
    new Animation({
        'canvas': canvas,
        'width': canvas.width,
        'height': canvas.height,
        'radius': 100,
        'linewidth': 10,        
        'interval': 20,
        'step': 1,
        'backcolor': '#666',
        'circlecolor': '#fff',
        'fillcolor': '#339999'
    }).start( 70 );
</script>
like image 20
Danijel Avatar answered Sep 18 '22 14:09

Danijel