You are previewing HTML5 Canvas.

HTML5 Canvas

Cover of HTML5 Canvas by Steve Fulton... Published by O'Reilly Media, Inc.
  1. HTML5 Canvas
    1. SPECIAL OFFER: Upgrade this ebook with O’Reilly
    2. A Note Regarding Supplemental Files
    3. Preface
      1. Running the Examples in the Book
      2. What You Need to Know
      3. How This Book Is Organized
      4. Conventions Used in This Book
      5. Using Code Examples
      6. We’d Like to Hear from You
      7. Safari® Books Online
      8. Acknowledgments
    4. 1. Introduction to HTML5 Canvas
      1. The Basic HTML Page
      2. Basic HTML We Will Use in This Book
      3. The Document Object Model (DOM) and Canvas
      4. JavaScript and Canvas
      5. HTML5 Canvas “Hello World!”
      6. Debugging with Console.log
      7. The 2D Context and the Current State
      8. The HTML5 Canvas Object
      9. Another Example: Guess The Letter
      10. What’s Next
    5. 2. Drawing on the Canvas
      1. The Basic File Setup for This Chapter
      2. The Basic Rectangle Shape
      3. The Canvas State
      4. Using Paths to Create Lines
      5. Advanced Path Methods
      6. Compositing on the Canvas
      7. Simple Canvas Transformations
      8. Filling Objects with Colors and Gradients
      9. Filling Shapes with Patterns
      10. Creating Shadows on Canvas Shapes
      11. What’s Next
    6. 3. The HTML5 Canvas Text API
      1. Displaying Basic Text
      2. Setting the Text Font
      3. Text and the Canvas Context
      4. Text with Gradients and Patterns
      5. Width, Height, Scale, and toDataURL() Revisited
      6. Final Version of Text Arranger
      7. What’s Next
    7. 4. Images on the Canvas
      1. The Basic File Setup for This Chapter
      2. Image Basics
      3. Simple Cell-Based Sprite Animation
      4. Advanced Cell-Based Animation
      5. Applying Rotation Transformations to an Image
      6. Creating a Grid of Tiles
      7. Zooming and Panning an Image
      8. Pixel Manipulation
      9. Copying from One Canvas to Another
      10. What’s Next
    8. 5. Math, Physics, and Animation
      1. Moving in a Straight Line
      2. Bouncing Off Walls
      3. Curve and Circular Movement
      4. Simple Gravity, Elasticity, and Friction
      5. Easing
      6. What’s Next?
    9. 6. Mixing HTML5 Video and Canvas
      1. HTML5 Video Support
      2. Converting Video Formats
      3. Basic HTML5 Video Implementation
      4. Preloading Video in JavaScript
      5. Video and the Canvas
      6. Video on the Canvas Examples
      7. Animation Revisited: Moving Videos
      8. What’s Next?
    10. 7. Working with Audio
      1. The Basic <audio> Tag
      2. Audio Formats
      3. Audio Tag Properties, Functions, and Events
      4. Playing a Sound with No Audio Tag
      5. Creating a Canvas Audio Player
      6. Case Study in Audio: Space Raiders Game
      7. What’s Next
    11. 8. Canvas Game Essentials
      1. Why Games in HTML5?
      2. Our Basic Game HTML5 File
      3. Our Game’s Design
      4. Game Graphics: Drawing with Paths
      5. Animating on the Canvas
      6. Applying Transformations to Game Graphics
      7. Game Graphic Transformations
      8. Game Object Physics and Animation
      9. A Basic Game Framework
      10. Putting It All Together
      11. The player Object
      12. Geo Blaster Game Algorithms
      13. The Geo Blaster Basic Full Source
      14. Rock Object Prototype
      15. What’s Next
    12. 9. Combining Bitmaps and Sound
      1. Geo Blaster Extended
      2. Creating a Dynamic Tile Sheet at Runtime
      3. A Simple Tile-Based Game
      4. What’s Next
    13. 10. Mobilizing Games with PhoneGap
      1. Going Mobile!
      2. Creating the iOS Application with PhoneGap
      3. Beyond the Canvas
      4. What’s Next
    14. 11. Further Explorations
      1. 3D with WebGL
      2. Multiplayer Applications with ElectroServer 5
      3. Conclusion
    15. Index
    16. About the Authors
    17. Colophon
    18. SPECIAL OFFER: Upgrade this ebook with O’Reilly

Image Basics

The Canvas API allows access to the DOM-defined Image object type through the use of the drawImage() method. The image can be defined in HTML, such as:

<img src="ship1.png" id="spaceship">

Or it can be defined in JavaScript. We create a new JavaScript Image instance like this:

var spaceShip = new Image();

We can then set the file source of the image by assigning a URL to the src attribute of our newly created Image object:

spaceShip.src = "ship1.png";

Preloading Images

Before an image can be called in code, we must ensure that it has properly loaded and is ready to be used. We do this by creating an event listener to fire off when the load event on the image occurs:

spaceShip.addEventListener('load', eventShipLoaded , false);

When the image is fully loaded, the eventShipLoaded() function will fire off. Inside this function we will then call drawScreen(), as we have in the previous chapters:

function eventShipLoaded() {


In practice, we would not create a separate event listener function for each loaded image. This code example works fine if your application contains only a single image. In Chapter 9, we will build a game with multiple image files (and sounds) and use a single listener function for all loaded resources.

Displaying an Image on the Canvas with drawImage()

Once we have an image loaded in, we can display it on the screen in a number of ways. The drawImage() Canvas method is used for displaying image data directly onto the canvas. drawImage() is overloaded and takes three separate sets of parameters, each allowing varied manipulation of both the image’s source pixels and the destination location for those pixels on the canvas. Let’s first look at the most basic:

drawImage(Image, dx, dy)

This function takes in three parameters: an Image object, and x and y values representing the top-left corner location to start painting the image on the canvas.

Here is the code we would use to place our spaceship image at the 0,0 location (the top-left corner) of the canvas:

context.drawImage(spaceShip, 0, 0);

If we want to place another copy at 50,50, we would simply make the same call but change the location:

context.drawImage(spaceShip, 50, 50);

Example 4-1 shows the full code for what we have done so far.

Example 4-1. Load and display an image file

var spaceShip = new Image();
spaceShip.addEventListener('load', eventShipLoaded , false);
spaceShip.src = "ship1.png";

function eventShipLoaded() {

function drawScreen() {

   context.drawImage(spaceShip, 0, 0);
   context.drawImage(spaceShip, 50, 50);


Figure 4-1 shows the 32×32 ship1.png file.

Load and display an image file

Figure 4-1. Load and display an image file

In practice, we would probably not put all of our drawing code directly into a function such as drawScreen(). It almost always makes more sense to create a separate function, such as placeShip(), shown here:

function drawScreen() {
   placeShip(context, spaceShip, 0, 0);
   placeShip(context, spaceShip, 50, 50);

function placeShip(ctx, obj, posX, posY, width, height) {
   if (width && height) {
     context.drawImage(obj, posX, posY, width, height);
   } else {
     context.drawImage(obj, posX, posY);

The placeShip() function accepts the context, the image object, the x and y positions, and a height and width. If a height and width are passed in, the first version of the drawScreen() function is called. If not, the second version is called. We will look at resizing images as they are drawn in the next section.

The ship1.png file we are using is a 32×32 pixel .png bitmap, which we have modified from Ari Feldman’s excellent SpriteLib. SpriteLib is a free library of pixel-based game sprites that Ari has made available for use in games and books. You can find the entire SpriteLib here:


The website for this book contains only the files necessary to complete the examples. We have modified Ari’s files to fit the needs of this book.

Figure 4-2 shows two copies of the image painted to the canvas. One of the copies has the top-left starting location of 0,0, and the other starts at 50,50.

Draw multiple objects with a single source

Figure 4-2. Draw multiple objects with a single source

Resizing an Image Painted to the Canvas

To paint and scale drawn images, we can also pass parameters into the drawImage() function. For example, this second version of drawImage() takes in an extra two parameters:

drawImage(Image, dx, dy, dw, dh)

dw and dh represent the width and height of the rectangle portion of the canvas where our source image will be painted. If we only want to scale the image to 64×64 or 16×16, we would use the following code:

context.drawImage(spaceShip, 0, 0,64,64);
context.drawImage(spaceShip, 0, 0,16,16);

Example 4-2 draws various sizes to the canvas.

Example 4-2. Resizing an image as it is drawn

function eventShipLoaded() {

function drawScreen() {

   context.drawImage(spaceShip, 0, 0);
   context.drawImage(spaceShip, 0, 34,32,32);
   context.drawImage(spaceShip, 0, 68,64,64);
   context.drawImage(spaceShip, 0, 140,16,16);

See Figure 4-3 for the output to this example.

Resizing an image as it is drawn

Figure 4-3. Resizing an image as it is drawn

In Example 4-2, we have added a gray box so we can better see the placement of the images on the canvas. The image we placed on the screen can scale in size as it is painted, saving us the calculation and steps necessary to use a matrix transformation on the object. The only caveat is that the scale origin point of reference is the top-left corner of the object. If we used a matrix operation, we could translate the origin point to the center of the object before applying the scale.

We have placed two 32×32 objects on the canvas to show that these two function calls are identical:

context.drawImage(spaceShip, 0, 0);
context.drawImage(spaceShip, 0, 34,32,32);

Aside from the fact that the second is placed 34 pixels below the first, the extra 32,32 at the end of the second call is unnecessary because it is the original size of the object. This demonstrates that the scale operation does not translate (or move) the object on any axis. The top-left corner of each is 0,0.

Copying Part of an Image to the Canvas

The third set of parameters that can be passed into drawImage() allows us to copy an arbitrary rectangle of data from a source image and place it onto the canvas. This image data can be resized as it is placed.

We are going to use a second source image for this set of operations: spaceships that have been laid out on what is called a tile sheet (also known as a sprite sheet, a texture sheet, or by many other names). This type of file layout refers to an image file that is broken up physically into rectangles of data. Usually these rectangles have an equal width and height. The “tiles” or “sprites” we will be using are 32 pixels wide by 32 pixels high, commonly referred to as 32×32 tiles.

Figure 4-4 shows a tile sheet with the grid lines turned on in the drawing application. These grid lines separate each of the tiles on the sheet.

The tile sheet inside a drawing program

Figure 4-4. The tile sheet inside a drawing program

Figure 4-5 is the actual tile sheet—without grid lines—that we will use for our further examples.

The tile sheet exported for use in an application

Figure 4-5. The tile sheet exported for use in an application

The structure of the parameters for this third version of the drawImage() function looks like this:

drawImage(Image, sx, sy, sw, sh, dx, dy, dw, dh)

sx and sy represent the “source positions” to start copying the source image to the canvas. sw and sh represent the width and height of the rectangle starting at sx and sy. That rectangle will be copied to the canvas at “destination” positions dx and dy. As with the previous drawImage() function, dw and dh represent the newly scaled width and height for the image.

Example 4-3 copies the second version of our spaceship (tile number 2) to the canvas and positions it at 50,50. It also scales the image to 64×64, producing the result shown in Figure 4-6.

Example 4-3. Using all of the drawImage() parameters

var tileSheet = new Image();
tileSheet.addEventListener('load', eventShipLoaded , false);

tileSheet.src = "ships.png";

function eventShipLoaded() {

function drawScreen() {
   //draw a background so we can see the Canvas edges
   context.fillStyle = "#aaaaaa";
   context.drawImage(tileSheet, 32, 0,32,32,50,50,64,64);

As you can see, we have changed the name of our Image instance to tileSheet because it represents more than just the source for the single ship image.

Using all of the drawImage() parameters

Figure 4-6. Using all of the drawImage() parameters

Now, let’s use this same concept to simulate animation using the tiles on our tile sheet.

The best content for your career. Discover unlimited learning on demand for around $1/day.