How to draw animated circles in HTML5 canvas

By bhagwatchouhan
How to draw animated circles in HTML5 canvas

This post explains the steps required to draw circles and apply simple animations with collision detection.

Step 1: Draw Circle

In this step, we will learn how to draw a circle in canvas using arc() method as explained below.

We have used the beginPath() method to begin our path and called the arc() method to add the circle operation. In the end, we have used the stroke() method to draw all the accumulated operations. In our case, we have only added a single circle to the path.

Method Signature - arc(x, y, radius, startAngle, endAngle, anticlockwise)

Method Parameters -

x - The x-coordinate of the center of Circle

y - The y-coordinate of the center of Circle

radius - The radius of the Circle

startAngle - Starting position of the Arc

endAngle - Starting position of the Arc

anticlockwise - Flag to change circle direction

// Single Circle - Get Canvas element by Id
var canvas1 = document.getElementById( "canvas1" );

// Set Canvas dimensions
canvas1.width   = 200;
canvas1.height  = 200;

// Get drawing context
var c1 = canvas1.getContext( '2d' );

// Begin Path
c1.beginPath();
// Arc Operation c1.arc( 50, 50, 30, 0, Math.PI * 2, false );
// Fill Stroke c1.stroke();

The above code draws a Circle by considering x-axis from left to right and y-axis from top to bottom.

 

Step 2: Draw multiple circles

In this step, we will draw multiple circles using a simple iteration using a for loop. We have also used the Math.random() method to get a different value of x and y coordinates to randomize the position of circles.

// Multiple Circle - Get Canvas element by Id
var canvas2 = document.getElementById("canvas2");

// Set Canvas dimensions
canvas2.width   = 200;
canvas2.height  = 200;

// Get drawing context
var c2 = canvas2.getContext('2d');

// Iterate to draw 4 circles
for( var i = 0; i < 4; i++ ) {
	// Generate x and y values between 0 to 140 considering 30 pt radius
  	var x = 30 + Math.random() * 140;
  	var y = 30 + Math.random() * 140;

	// Begin Path
	c2.beginPath();
// Arc Operation c2.arc( x, y, 30, 0, Math.PI * 2, false ); // Fill Stroke c2.stroke(); }

 

Step 3: Animate one circle

To animate the circle we have used requestAnimationFrame( functionName ) method. We have used dx and dy to control change in circle motion in x and y-direction respectively.

To move the circle, we increment the change in x and y values by 1. We have used dx and dy to control the circle's animation speed. If x and y values grow beyond the 50 to 150 range, we reverse the change by making dx and dy values negative and vice versa. The function clearRect() is used to clear the drawings made on Canvas in previous iterations.

// Single Animated Circle - Get Canvas element by Id
var canvas3 = document.getElementById("canvas3");

// Set Canvas dimensions
canvas3.width   = 200;
canvas3.height  = 200;

// Get drawing context
var c3 = canvas3.getContext( '2d' );

// Radius
var radius = 50;
// Starting Position var x = radius + Math.random() * ( 200 - radius * 2 ); var y = radius + Math.random() * ( 200 - radius * 2 );
// Speed in x and y direction var dx = (Math.random() - 0.5) * 2; var dy = (Math.random() - 0.5) * 2; function animate3() { requestAnimationFrame( animate3 ); c3.clearRect( 0, 0 , 200, 200 ); if( x + radius > 200 || x - radius < 0 ) { dx = -dx; } if( y + radius > 200 || y - radius < 0 ) { dy = -dy; } x += dx; y += dy; c3.beginPath(); c3.arc( x, y, 50, 0, Math.PI * 2, false ); c3.stroke(); } // Animate the Circle animate3();

The above-mentioned code adds an animated circle within the canvas boundaries.

 

Step 4: Animate multiple circles

In order to draw and animate multiple circles, we have used circle class having draw and update function to preserve the location of each circle. The draw function is used to draw the circle and update function is used to control circle motion.

Similar to step 3, we will iterate and make multiple circles using circle class objects. We have used the function animate4() having for loop as our render or animation loop to iterate all circle objects and call the update method to change circle position.

// Multiple Animated Circle - Get Canvas element by Id
var canvas4 = document.getElementById( "canvas4" );
// Set Canvas dimensions canvas4.width = 200; canvas4.height = 200;
// Get drawing context var c4 = canvas4.getContext( '2d' );
// The Circle class function Circle( x, y, dx, dy, radius ) { this.x = x; this.y = y; this.dx = dx; this.dy = dy; this.radius = radius; this.draw = function() { c4.beginPath(); c4.arc( this.x, this.y, this.radius, 0, Math.PI * 2, false ); c4.strokeStyle = "blue"; c4.stroke(); }
this.update = function() { if( this.x + this.radius > 200 || this.x - this.radius < 0 ) { this.dx = -this.dx; }
if( this.y + this.radius > 200 || this.y - this.radius < 0 ) {
this.dy = -this.dy; }
this.x += this.dx; this.y += this.dy; this.draw(); } }
var circles = [];
// Radius var radius = 50;
for( var i = 0; i < 5; i++ ) {
// Starting Position var x = Math.random() * ( 200 - radius * 2 ) + radius; var y = Math.random() * ( 200 - radius * 2) + radius;
// Speed in x and y direction var dx = ( Math.random() - 0.5 ) * 2; var dy = ( Math.random() - 0.5 ) * 2;
circles.push( new Circle( x, y, dx, dy, radius ) ); }
function animate4() { requestAnimationFrame( animate4 ); c4.clearRect( 0, 0, 200, 200 ); for( var r = 0; r < 5; r++ ) { circles[ r ].update(); } }
animate4(); 

The animated circles with default stroke will look similar to the output

 

Step 5: Add colors to Animated Circles

In this step, we will add the color property to the Circle class and use a different color for each circle to create minor variations.

// Multiple Colored Animated Circle - Get Canvas element by Id
var canvas5 = document.getElementById( "canvas5" );
// Set Canvas dimensions canvas5.width = 200; canvas5.height = 200;
// Get drawing context var c5 = canvas5.getContext( '2d' );
// The Circle class function ColoredCircle( x, y, dx, dy, radius, color ) { this.x = x; this.y = y; this.dx = dx; this.dy = dy; this.radius = radius; this.color = color; this.draw = function() {
c5.beginPath(); c5.arc( this.x, this.y, this.radius, 0, Math.PI * 2, false );
c5.strokeStyle = this.color;
c5.stroke(); } this.update = function() {
if( this.x + this.radius > 200 || this.x - this.radius < 0 ) {
this.dx = -this.dx; } if( this.y + this.radius > 200 || this.y - this.radius < 0 ) {
this.dy = -this.dy; }
this.x += this.dx;
this.y += this.dy; this.draw(); } }
var coloredCircles = []; var circleColors = [ 'red', 'green', 'blue', 'yellow', 'orange' ];
// Radius var radius = 50;
for( var i = 0; i < 5; i++ ) { // Starting Position var x = Math.random() * ( 200 - radius * 2 ) + radius; var y = Math.random() * ( 200 - radius * 2) + radius;
// Speed in x and y direction var dx = ( Math.random() - 0.5 ) * 2; var dy = ( Math.random() - 0.5 ) * 2;
// Color var color = circleColors[ i ];
coloredCircles.push( new ColoredCircle( x, y, dx, dy, radius, color ) ); }
function animate5() { requestAnimationFrame( animate5 ); c5.clearRect( 0, 0, 200, 200 ); for( var r = 0; r < 5; r++ ) { coloredCircles[ r ].update(); } }
animate5();

Share this blog:

Profile picture for user bhagwatchouhan
bhagwatchouhan