Bouncing a Ball Around with HTML5 and JavaScript

As many of you right now, the <canvas> element is one of the most popular additions to the HTML5 standards. It is widely supported by popular browsers like Firefox, Chrome, Safari and Opera (Internet Explorer supports it in their IE9 beta version). This guide will explore the use of HTML5′s <canvas> element through a fun example: bouncing a blue ball around.
Final Result
An Overview of HTML5′s Canvas
The <canvas> tag primarily allows you to render 2D shapes and images dynamically using math functions. Practical uses for this are things such as dynamic charts that are populated by data from a relational database like MySQL or web games that rely solely on open technologies (JavaScript/HTML).
While <canvas> in HTML merely allows you to define a region in terms of width and height, everything else related to the actual drawing of the shapes is done through JavaScript via a full set of drawing functions and methods (collectively known as the Canvas 2D API).
So that we may explore the <canvas> element through a hands-on approach, we will create a ball that will be bouncing around using HTML5 specifications and JavaScript.
Note that we will skip CSS because this guide is about HTML5 and JavaScript. CSS doesn’t play a part in the appearance and functionality of the bouncing ball, so we don’t need to discuss it.
HTML
To start, you will need to create a basic HTML document. It’s best if you follow along with me as we go — so go ahead and create your HTML document now.
Let’s add our <canvas> element inside the <body> tag. Though we only have one <canvas> element in our HTML for this example, I have still assigned an ID to it (myCanvas) just to make it easier/quicker to select it later on via JavaScript. I also defined the element’s dimensions (width/height), however, you could just as well do that via CSS by targeting the #myCanvas ID.
<body> <canvas id="myCanvas" width="500" height="400"> </canvas> </body>
JavaScript
Now let us start with the actual work of creating our shapes in JavaScript.
Draw the Circle
We are going to draw a circle using the arc[1] and fill[2] methods. The syntax is self-explanatory, especially if you’re familiar with JavaScript. Basically, we define the context, initiate the drawing, then we use color and style methods to fill in the color and dictate the shape (using a Math object for a circle).
Then when the HTML document is loaded (body’s onLoad), we just call the init() function. Note that it’s better to write unobtrusive JavaScript but I would like to keep this exploration brief, simple and as self-explanatory in code as possible.
<script>
var context;
function init()
{
context= myCanvas.getContext('2d');
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100,100 on the canvas
context.arc(100,100,20,0,Math.PI*2,true); context.closePath();
context.fill();
}
</script>
<body onLoad="init();">
<canvas id="myCanvas" width="300" height="300" >
</canvas>
</body>
Save the HTML file and open it in a browser that supports <canvas> and HTML5 (latest Safari, Opera, Chrome, and Firefox versions) so that you can preview the code.
If everything is fine, you should be seeing a blue circle that has a radius of 20px (or in other words, 40px in diameter).

Move the Circle
Now that we have the circle, let’s try to move it. We’ll replace the hardcoded values of the coordinates in the .arc method (100, 100 — the first two arguments) with variables x and y, which we will then increment by an amount of dx and dy.
Also since we need to redraw the circle at the new positions, we’ll move the code into a function called draw() and call it every 10ms using JavaScript’s setInterval() function.
<script>
var context;
var x=100;
var y=200;
var dx=5;
var dy=5;
function init()
{
context= myCanvas.getContext('2d');
setInterval(draw,10);
}
function draw()
{
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100,100 on the canvas
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
x+=dx;
y+=dy;
}
</script>
<body onLoad="init();">
<canvas id="myCanvas" width="300" height="300" >
</canvas>
</body>
Save the file and test your work in your web browser.
Uh oh — Houston, we have a problem. The circle is actually forming a line (see the image below).

This is because each time the draw() function is called, it draws a circle at the new coordinates without removing the old ones. That’s how the getContext object works so it’s not a bug; it doesn’t really move the circle and, instead, it draws a circle at the new coordinates each time the function is called.
To erase the old circles, we’ll need to call the clearRect method right at the start of our draw() function so that it clears out the previous circle before it draws the new one.
<script>
var context;
var x=100;
var y=100;
var dx=5;
var dy=5;
function init()
{
context= myCanvas.getContext('2d');
setInterval(draw,10);
}
function draw()
{
context.clearRect(0,0, 300,300);
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100,100 on the canvas
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
x+=dx;
y+=dy;
}
</script>
<body onLoad="init();">
<canvas id="myCanvas" width="300" height="300" >
</canvas>
</body>
Save the file and refresh your browser and see the ball move out of the screen nicely.
Limit the Area with an Imaginary Wall
Now it’s time to bounce the ball off the corners of the <canvas> element.
Well, that’s easy: All you need to do is check if the values of x and y are beyond the canvas dimensions, and if so, we need to reverse the direction by setting values of dx and dy to the negative values.
<script>
var context;
var x=100;
var y=200;
var dx=5;
var dy=5;
function init()
{
context= myCanvas.getContext('2d');
setInterval(draw,10);
}
function draw()
{
context.clearRect(0,0, 300,300);
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100,100 on the canvas
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
// Boundary Logic
if( x<0 || x>300) dx=-dx;
if( y<0 || y>300) dy=-dy;
x+=dx;
y+=dy;
}
</script>
<body onLoad="init();">
<canvas id="myCanvas" width="300" height="300" >
</canvas>
</body>
If all goes well, you should see a ball bouncing around the four corners of the canvas element (like in the demo). Awesome, right?
Conclusion
This bouncing ball is a fundamental concept to many of the game development logic and it can be easily extended to build a ping-pong game or a breaker-type of game.
But more than the actual demonstration itself, what I hope to have imparted here is the motivation to explore the Canvas API to see if you can push your limits and be on the cutting edge. So in order to help you continue your journey into HTML5, I would like to share with you some resources to check out:
- Canvas 2D API Specification 1.0: Latest W3C draft
- How to Make an HTML5 iPhone App: An example of using HTML5 for creating a Tetris game (uses Canvas)
- The Only HTML5 Resources You Need for Getting Up to Speed: A collection of resources to help you get caught up with HTML5 developments
- The State of HTML5 Apps: An introduction to using HTML5 and open technologies to build robust web applications
References
- The Canvas 2D API 1.0 Specification - 3.4 Colors and styles
- The Canvas 2D API 1.0 Specification – 3.8 Complex shapes (paths)
Related Content
- 20 HTML Best Practices You Should Follow
- CSS3 Card Trick: A Fun CSS3 Experiment
- 10 Interesting CSS3 Experiments and Demos
- Related categories: HTML and Web Development

Vinci Rufus is web designer/developer who dabbles and enjoys working with CSS, HTML5, CakePHP and Flex. He runs a design and development firm called 
38 Comments
Don Rogers
September 11th, 2010
Very cool, and no Flash! Nice!
Alex
September 11th, 2010
Thanks for the tutorial. It’s very helpful. The last code does not work in Chrome but the demo works.
Alex
September 11th, 2010
x+=dx; y+=dy; should not be in the bracket
MichalBe
September 11th, 2010
With boundary and movement logic you write here ball could only bounce from the walls with 90 degrees and moves diagonally. You could implement some trigonometric functions for more realistic movement.
JC
September 11th, 2010
Nice post. thanks
Young
September 11th, 2010
That’s fun. I’d like to see more fun HTML5 things like this on SR. And I agree with Alex – you don’t need to increment x and y again inside logic.
Wp Themes
September 11th, 2010
Looks fantastic! seems to me html5 is going to replace a lot of .gif images :)
Balkrishna
September 12th, 2010
At the wall , the ball seems to suddenly break by half .. how to correct it …
Sean
September 12th, 2010
very nice…so much to learn
Jacob Gube
September 12th, 2010
Sorry guys, the boundary logic code was messed up (my fault). It was correct in the source, but the code in the article had the x/y increments included in the second control structure.
MichalBe
September 12th, 2010
@Balkrishna
st calculate the collision between the wall and the edge of the circle, not the central point of it.
For radius = 20 it will be like this:
// Boundary Logic
if( x300-20) dx=-dx;
if( y300-20) dy=-dy;
And don’t forget to increase X coord in starting position of the ball, because it won’t start to move properly. Corrected example:
http://jsbin.com/arebu
MichalBe
September 12th, 2010
I think security filter removes some parts of my comment, check the link for right version.
Vinci Rufus
September 12th, 2010
@Balkrishna MichalBe is right
you just need to minus the radius of the ball from the conditions. like this
if( x<(0+20) || x>(300-20))
dx=-dx;
if( y<(0+20) || y>(300-20))
dy=-dy;
Also don’t forget to set var x=30;
@MichalBe, I was tying to keep it simple and hence didn’t want to get into trignometric functions at this stage.
Moreover when the ball is bouncing off the walls its always going to be at right angles.
You could try dx=4; and dy=6; to get a different variation of the bounce.
Tom
September 12th, 2010
This is awesome, I think I am now going to spend the day playing around with the canvas element.
Craig
September 12th, 2010
Great use of HTML5, easy to follow tutorial, Thanks!
Webdp
September 13th, 2010
great html5 example, even if it is with javascript.
Theo
September 13th, 2010
Cool stuff, thanks for the tut !
Jacob Gube
September 13th, 2010
@Webdp: HTML5 is for markup. To make it functional, you’ll need JS. It’s a misconception that the new HTML5 stuff doesn’t require JS. This is the same for the new video and audio elements and offline storage; even though it’s defined under HTML5 specs, it still needs JS (via APIs) to be functional — e.g. playback for video/audio and actual storage and retrieval of data for offline storage — because HTML5 is a markup language.
Matt
September 13th, 2010
Hey, can anybody suggest how to clone more isntances of the ball – i.e. so that we have several of them bouncing around inside the box. I am pretty poor at javascript stuff, especially when it comes to object oriented stuff. Please let me know !
Matt
Yogendra
September 14th, 2010
A very descriptive and DYI post.This was my first time to touch on canvas and it was possible because of this post only.
Thanks Vinci.
Yuriy Romadin
September 14th, 2010
It’s awesome. Never knew how this thins are done. Thanks!
Ghostmancer
September 25th, 2010
Nice tutorial! But one question: Can you use multiple balls? Because Multiple balls aren’t working for me. I will keep trying.
sam
November 22nd, 2010
how would you make this so it bounces off the edges of the screen?
jan drasnar
December 8th, 2010
Hi,
great code example, thanks for that!
do you know how to:
1) add more balls
2) define that balls would become translucent
Thanks alot
my code example
var context;
var dx=4;
var dy=4;
var y=0;
var x=50;
function draw(){
context= myCanvas.getContext(’2d’);
context.clearRect(0,0,267,256);
context.beginPath();
context.fillStyle=”#ffffff”;
context.arc(x,y,10,0,Math.PI*2,true);
context.closePath();
context.fill();
if( x>80 || x<30)
dx=-dx;
if( y<300 )
x+=dx;
y+=dy;
}
setInterval(draw,50);
or
http://drash.internetstation.cz/test/bounce/
Vinci
December 11th, 2010
Hi,
Sorry about not being able to answer this earlier.
To create multiple objects animating you’ll need to create a new instance of the canvas object each time and use it to create the different objects.
Here is a quick code that I’ve put up which does this for you.
http://www.vinznet.com/index.php?id=123
Chip
February 11th, 2011
Nice demo. Just a quick question though, what if you want to have a bouncing cube instead of a ball. What would you need to do?
ahmed
February 28th, 2011
nice demo :D can any one tell me how to let the ball moves with mouse move(use mouse coordinate)
thx :D
olivier
April 18th, 2011
Nice post,
Is it possible to stop the ball when you clic on it ? How will you attach the event ?
thanks
JS
June 5th, 2011
Great tutorial thanks! How would I go about replacing those balls with actual images (jpg/png)?
Jesse
July 17th, 2011
can someone please explain the logic behind the boundary logic..it works, but for some reason it doesn’t make sense…once x or y hits a wall dx becomes -dx or -dy..it’s supposed to stay negative then forever right?!
if( x280) dx=-dx;
if( y280) dy=-dy;
x+=dx;
y+=dy;
Jesse
July 17th, 2011
if( x280) dx=-dx;
if( y280) dy=-dy;
x+=dx;
y+=dy;
sorry meant this one
nithin
July 27th, 2011
nice one really helpfull..
Intizar
September 8th, 2011
really nice one. very helpful I was searching such type of tutorial
John L
September 26th, 2011
Your article was very helpful. Thanks.
gauss11
October 25th, 2011
Really cool.
Thanks
Dovid G.
November 8th, 2011
@Jesse (If you’re still watching the comments)
What’s happening is this, suppose dx = 5.
If I were to declare x = -dx, that would mean x = -5.
Now if I declare x = -x, it’s like saying x equals negative negative 5 (x = – -5) which reverses the negative to a positive. So now x = 5. If I do x = -x again, then it’s back to negative 5, if I do it again then it’s positive 5.
So when the ball hits the wall dx reverses it self from positive to negative, or negative to positive, and it’s all accomplished by dx=-dx. For either it’s a true negative -dx or a positive -(-dx).
Hitu
June 15th, 2012
Nice Article
akash
June 15th, 2012
hello,,i want some balls to be moving in a box but if someone moves the cursor to one of the ball then it should stop moving automatically and if we click on that ball then it should open some specified link.But it should be purely using javascript,css,html5 and jquery..
can anyone help?
Leave a Comment