Create a Sprite Animation With HTML5 Canvas and JavaScript
Short Description
Javascript...
Description
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
Create a Sprite Animation with HTML5 Canvas and JavaScript by William Malone
Sprite animations can be drawn on HTML5 canvas and animated through JavaScript. Animations are useful in game and interactive application development. Several frames of an animation can be included in a single image and using HTML5 canvas and JavaScript we can draw a single frame at a time. This tutorial will describe how HTML5 sprite animations work. We will go step by step through the process of creating a sprite animation. At the end of the this article we will use the animation we created in a simple HTML5 game. The example code is based off the game development framework: BlocksJS. The full game framework with additional features can be downloaded from BlocksJS on GitHub. The source code for the examples in the article is available at the end.
What is a Sprite Animation? Two dimensional frame-based animation can be achieved on HTML5 canvas by rendering an area of a single image on a given interval. The following five frame animation is rendered on a HTML5 canvas at one frame per second (1 fps).
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 1 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
Using the drawImage method of the canvas context we can change the source position to only draw a cropped portion of one image called a "sprite sheet".
What is a Sprite Sheet? HTML5 canvas animation sprite sheets are fundamentally the same as CSS sprite sheets. A sprite sheet consists of muliple frames in one image. The following sprite sheet has 10 frames. The width of the image is 460 pixels. Therefore the frame width is 460/10 or 46 pixels.
Now Let's Create a Sprite Animation Let's start by loading the sprite sheet image for the coin animation. Create a new Image object and then set its src property to the filename of the image which will load the image. var coinImage = new Image(); coinImage.src = "images/coin-sprite-animation.png"; Next we define the sprite object so we can create one (or more later). Invoking the object will simply return an object with three public properties. function sprite (options) { var that = {}; that.context = options.context; that.width = options.width; that.height = options.height; that.image = options.image; return that; } http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 2 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
Grab access to the canvas element using getElementById and then set its dimensions. We will need the canvas's context to draw to later. var canvas = document.getElementById("coinAnimation"); canvas.width = 100; canvas.height = 100; Now we can create a sprite object which we will call coin. Using the options parameter we set properties of the object which will specify: the context of the canvas on which the sprite will be drawn, the sprite dimensions, and the sprite sheet image. var coin = sprite({ context: canvas.getContext("2d"), width: 100, height: 100, image: coinImage });
DrawImage Method The key to creating sprites from one image is that the context's drawImage method allows us to render a cropped section of the source image to the canvas. context.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh) img Source image object Sprite sheet sx Source x Frame index times frame width sy Source y 0 sw Source width Frame width sh Source height Frame height dx Destination x 0 dy Destination y 0 http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 3 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
dw Destination width Frame width dh Destination height Frame height
We will use the drawImage method in our sprite's render method to draw one frame at a time.
Render Time to draw to the canvas. The sprite function will need a render method that invokes the drawImage method on the canvas' context. The parameters specify the source image and the bounding rectangle dimensions and position of the source sprite sheet and the destination canvas context. function sprite (options) { ... that.render = function () { // Draw the animation
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 4 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
that.context.drawImage( that.image, 0, 0, that.width, that.height, 0, 0, that.width, that.height); }; ... } Oh, and call the render method. coin.render();
We have drawn the coin, but where is the animation?
Update We need a method so we can update the position of the sprite sheet's bound rectangle. Let's call it... update. We need also need to keep track of where the animation is so let's create some properties:
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 5 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
frameIndex The current frame to be displayed tickCount The number updates since the current frame was first displayed ticksPerFrame The number updates until the next frame should be displayed We could just increment the frame index every time we call the update method, but when running a game at 60 frames per second we might want the animation to run at a slower fps. Tracking the ticks let's use delay the animation speed. For example we could run the sprite animation at 15 fps by setting the ticksPerFrame to 4 on game loop running at 60 fps. Each time the update method is called, the tick count is incremented. If the tick count reaches the ticks per frame the frame index increments the tick count resets to zero. function sprite (options) { var that = {}, frameIndex = 0, tickCount = 0, ticksPerFrame = ticksPerFrame || 0; ... that.update = function () { tickCount += 1; if (tickCount > ticksPerFrame) {
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 6 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
tickCount = 0; // Go to the next frame frameIndex += 1; } }; ... } The render method can now move the bounding rectangle of the source sprite sheet based on the frame index to be displayed by replacing the sprite width with the frame width: that.width is replaced with that.width / numberOfFrames. function sprite (options) { ... that.render = function () { // Draw the animation that.context.drawImage( that.image, frameIndex * that.width / numberOfFrames, 0, that.width / numberOfFrames, that.height, 0, 0, that.width / numberOfFrames, http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 7 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
that.height); }; ... } This works until the frame index is greater than the number of frames. We need a new property numberOfFrames and a conditional to ignore out of range values. function sprite (options) { var that = {}, frameIndex = 0, tickCount = 0, ticksPerFrame = 0, numberOfFrames = options.numberOfFrames || 1; ... that.update = function () { tickCount += 1; if (tickCount > ticksPerFrame) { tickCount = 0; // If the current frame index is in range if (frameIndex < numberOfFrames - 1) { // Go to the next frame http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 8 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
frameIndex += 1; } } }; ... } We want our coin to keep spinning after the first go around. We will need a new loop property and a conditional which resets the frame index and tick count if the last frame. function sprite (options) { ... that.loop = options.loop; that.update = function () { tickCount += 1; if (tickCount > ticksPerFrame) { tickCount = 0; // If the current frame index is in range if (frameIndex < numberOfFrames - 1) { // Go to the next frame frameIndex += 1; } else if (that.loop) { http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 9 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
frameIndex = 0; } } }; ... } But wait! Without a loop the update will only run once. We need to run the update on a loop...
RequestAnimationFrame We use requestAnimationFrame (See Paul Irish's post for a requestAnimationFrame polyfill for support in older browsers) to update and render the sprite at the same rate that the browser repaints. function gameLoop () { window.requestAnimationFrame(gameLoop); coin.update(); coin.render(); } // Start the game loop as soon as the sprite sheet is loaded coinImage.addEventListener("load", gameLoop);
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 10 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
Close, but something is not quite right.
ClearRect Method The clearRect method allows us to clear a region of the destination canvas between animation frames. context.clearRect(x, y, width, height) x Clear rectangle x position y Clear rectangle y position width Clear rectangle width height Clear rectangle height
that.render = function () { // Clear the canvas context.clearRect(0, 0, that.width, that.height); // Draw the animation that.context.drawImage( that.image, frameIndex * that.width / numberOfFrames, 0, that.width, that.height, 0, 0, http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 11 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
that.width, that.height); }; }; Clearing the canvas between frames gives us our complete sprite animation.
Sprite Animation Demo Demo can be loaded here or downloaded at the end of the article.
Coin Tap Game Now that we have learned how to create a sprite animation on HTML5 canvas we can use the game loop and animation to create a game. Let's keep the game simple: tap a coin to get points. To create our game we need to add a couple of event listeners for desktop (mousedown) and mobile (touchstart) and then use a simple circle collision detection to determine if the coin is tapped. If a coin is hit we remove the coin and create a new one resulting in a score based on the coin size. When creating new coins the size and speed of spin are randomized. We are drawing more than one sprite on the canvas now, so instead of clearing the canvas when we render a sprite we need to we need to clear the canvas at the beginning the game loop. If we didn't we would clear the all the previous sprites. With these updates we can create our Coin Tap Game; let's give it a try!
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 12 of 13
Create a Sprite Animation with HTML5 Canvas and JavaScript { William Malone }
9/16/14, 12:30 AM
192
Download Source Code Sprite Animation Demo / Coin Tap Game BlocksJS on GitHub
Related Articles Create HTML5 Drawing App HTML5 Game Character Maximum iOS Image Size
Share this Article
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Page 13 of 13
View more...
Comments