How to animate canvas graphics (HTML)
[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]
The canvas element is a drawable region on your HTML document that you can use JavaScript for generating graphics such as animations, graphs, and games. This topic gets you started by describing the steps needed to animate a basic drawing using the canvas element.
Prerequisites
This topic assumes that you:
- Can create a basic Windows app using JavaScript that uses the Windows Library for JavaScript template.
- Have a basic understanding of HTML and JavaScript.
For instructions on creating your first Windows app using JavaScript, see Create your first Windows Store app using JavaScript. For instructions on using the WinJS template, see How To Obtain and Use the WinJS Toolkit.
Instructions
Step 1: Timing the animation
Using the requestAnimationFrame method, you begin an animation by specifying a function to call (callback) whenever it's time to update your animation for the next repaint:
requestAnimationFrame(animationFunction);
requestAnimationFrame takes page visibility and the display's refresh rate into account to determine how many frames per second to allocate to the animation (that is, call animationFunction
).
Our JavaScript example draws an animated circle that moves in a spiral motion around a larger circle.
requestAnimationFrame(draw);
Here is our animation (results may vary, faster hardware results in more closely paced circles):
Step 2: Drawing the image
Clear the canvas
You'll need to clear the canvas before drawing each frame.
There are various methods for clearing a canvas, or parts of an image, such as clearing certain areas using the
globalCompositOperation
property or by clipping paths using theclip
method. The simplest way to clear a canvas is to use theclearRect
method.In our example the
clearRect
method is used to clear the entire canvas, but to make it easier to see the effects of drawing our image, theclearRect
method is commented out. If this line of code were uncommented, you would see a single circle spiraling around in a larger circular orbit and its trail would be cleared before each frame is drawn.// The clearRect method clears the entire canvas. context.clearRect(0, 0, 160, 160);
Save the canvas state
When drawing your image you might change some of the settings such as styles or transformations. If you want to use the original settings when you begin each redraw of the image, you can use the
save
method.The
save
andrestore
methods are used to save and retrieve the canvas state on a stack. The canvas state consists of all of the styles and transformations that have been applied. Every time thesave
method is called the current canvas state is saved on the stack. Therestore
method returns the latest saved state from the stack.In our example, we use the
save
method just prior to setting some transforms to draw and move the animated circle.// Save the canvas state. context.save();
Draw the image
While drawing the image to the canvas, you can use two transformations to make changes to your image; the translate and the rotate methods.
The translate method is used to move the canvas and its origin to a different point in the canvas grid:
translate(x, y)
This method takes two arguments; x is the amount the canvas is moved to the left or right, and y is the amount it's moved up or down.
It's a good idea to save the canvas state before doing any transformations as it is easier to call the
restore
method than having to do a reverse translation to return the canvas to its original state. Thetranslate
method allows you to place the image anywhere on the canvas without having to manually adjust coordinates.The
rotate
method is used to rotate the canvas around the current origin. This method has only one parameter and that’s the angle the canvas is rotated, measured in radians.rotate(angle)
The rotation moves clockwise, and the rotation center point is always the canvas origin (the top left corner). To move the center point you’ll need to move the canvas using the
translate
method.In our example we're going to alternate a few calls to the
translate
androtate
methods. The first call to thetranslate
method will center the animation on the canvas.Next, we make two sets of calls to the
rotate
andtranslate
methods. The first calls to therotate
andtranslate
methods will produce a small circle that is drawn around the canvas in a large loop. The second set of calls will produce a small circle that is drawn in a much smaller orbit.The canvas size is set to 160 pixels high and 160 pixels wide, so we’ll set the translate method’s x and y coordinates equal to 80 so that our overall animation is centered in the canvas.
// centers the image on the canvas context.translate(80, 80);
We begin our first call to the
rotate
method by using thedate
object to calculate therotate
method's parameter. This parameter is the angle that the canvas is to be rotated.var time = new Date(); context.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
Note that the value used to calculate
getSeconds
is 60 and the value to calculate thegetMilliseconds
is 60,000.The
translate
method moves the x coordinate which moves the rotating circle around the canvas in a large orbit.// Translate determines the size of the circle's orbit. context.translate(50, 0);
This is the effect of the first
rotate
andtranslate
methods:The next two calls to the
rotate
andtranslate
methods create a smaller orbit of looping circles.// Rotate causes the circle to move in a small orbit. context.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() ); // Translate determines the size of the orbit. context.translate(0, 5);
Note that in calculating the angle for the second rotate call, the value used to calculate
getSeconds
is 6 and the value to calculate thegetMilliseconds
is 6,000.If the first
rotate
andtranslate
methods are commented out here is what our secondrotate
andtranslate
methods would draw:After all the repositioning has been set, the circle is drawn on the canvas.
// This draws the repositioned circle context.beginPath(); context.arc(5, 5, 4, 0, Math.PI*2, true); context.stroke();
Restore the canvas state
We saved the canvas state earlier, in step b, so now we reset the canvas state for the next frame to be drawn.
// Restores the canvas to the previous state context.restore();
Complete Examples
Animated graphic
This JavaScript example draws an animated circle that moves in a spiral motion around a larger circle.
window.onload = init;
// As an optimization, make "context" a global variable that is only set once.
var context;
function init(){
context = document.getElementById('canvas').getContext('2d');
window.requestAnimationFrame(draw);
} // init
function draw() {
// Save the canvas state.
context.save();
// context.clearRect(0, 0, 160, 160);
// centers the image on the canvas
context.translate(80, 80);
// Rotate moves the spiraling circle around the canvas in a large orbit.
var time = new Date();
context.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
// Translate determines the location of the small circle.
context.translate(50, 0);
// Rotate causes the circle to spiral as it circles around the canvas.
context.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
// determines the size of the loop
context.translate(0, 5);
// This draws the circle
context.beginPath();
context.arc(5, 5, 4, 0, Math.PI*2, true);
context.stroke();
// Restores the canvas to the previous state
context.restore();
window.requestAnimationFrame(draw);
} // draw
This is an example of a Cascading Style Sheets (CSS) that creates a black border around a canvas element.
/* style the canvas element with a black border. */
canvas { border: 1px solid black; }
This HTML file creates a canvas element and uses external JavaScript and CSS files.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="myJavascript.js"></script>
<link Rel="stylesheet" Href="myStyle.css" Type="text/css">
</head>
<body>
<canvas id="canvas" width="160" height="160" />
</body>
</html>