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();