How To Load And Draw Images With HTML5 Canvas

For my previous tutorials I have been drawing basic shapes like rectangles to explain concepts. For tutorials and prototypes, this is fine. If you want to create a real game, it is important that you can draw images to the screen. Before these images can be displayed, they need to be loaded first. This tutorial explains how to load images at the start of your game and how to display the loaded images afterwards in a render loop. During the loading of the images, a preloader is displayed. A working example is provided including the full source code.

How To Load And Draw Images With HTML5 Canvas

How To Load And Draw Images With HTML5 Canvas

Click here to go directly to the end of this article and view the demo.

Loading Images

To load a single image, we first have to create an Image object. After the object is created, we set the src property of the image to the location of the image we want to load. The image doesn’t get loaded directly, it takes some time before the image is ready to be displayed. If we want to know when the image is ready, we must add an event handler to the onload event of the image. The onload event must be set, before we set the src property, otherwise we could miss the event. The code below shows how to load a single image.

1
2
3
4
5
6
7
8
9
10
// Create the image object
var image = new Image();
 
// Add onload event handler
image.onload = function () {
        // Done loading, now we can use the image
};
 
// Set the source url of the image
image.src = "image1.png";

Using the basic image loading code, we can create a function that takes an array of image files and loads all of our images at the same time. We could use this function at the start of a game to initialize our image resources. The function uses a couple of global variables that we can use to test if the image resources are actually loaded and ready. We use the global variables later in this tutorial to create a preloader.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Image loading global variables
var loadcount = 0;
var loadtotal = 0;
var preloaded = false;
 
// Load images
function loadImages(imagefiles) {
    // Initialize variables
    loadcount = 0;
    loadtotal = imagefiles.length;
    preloaded = false;
 
    // Load the images
    var loadedimages = [];
    for (var i=0; i<imagefiles.length; i++) {
        // Create the image object
        var image = new Image();
 
        // Add onload event handler
        image.onload = function () {
            loadcount++;
            if (loadcount == loadtotal) {
                // Done loading
                preloaded = true;
            }
        };
 
        // Set the source url of the image
        image.src = imagefiles[i];
 
        // Save to the image array
        loadedimages[i] = image;
    }
 
    // Return an array of images
    return loadedimages;
}

The function loadImages takes as input an array of filenames and returns an array of images in the same order as the input array. We can call the function like this:

1
var images = loadImages(["sprite1.png", "sprite2.png", "sprite3.png"]);

Draw And Scale Images

Now that we know how to load images, we want to draw them to the canvas. Drawing images is easy, if we have a context of the canvas and a loaded Image. We use the drawImage function and specify the image, dx and dy parameters to draw an image at a specified x and y position.

1
context.drawImage(image, dx, dy)

If you want to scale the output image, you can specify the optional parameters dWidth and dHeight as specified in the API. It is also possible to only draw a part of the source image by specifying a rectangle using the sx, sy, sWidth and sHeight parameters.

1
2
context.drawImage(image, dx, dy, dWidth, dHeight);
context.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

Here is a complete example, that uses a canvas with id viewport and loads and draws the image image1.png.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
window.onload = function() {
    // Get the canvas and context
    var canvas = document.getElementById("viewport"); 
    var context = canvas.getContext("2d");
 
    // Create the image object
    var image = new Image();
 
    // Add onload event handler
    image.onload = function () {
        // Done loading, now we can use the image
        context.drawImage(image, 10, 10);
    };
 
    // Set the source url of the image
    image.src = "image1.png";
};

A Simple Preloader

Before a game can start, all of the resources need to be loaded first. While we wait on the images to be loaded, we can show a loading screen to the player. This loading screen is called a preloader. To implement the preloader, I’m going to modify the code of the HTML5 Canvas Basic Game Framework from a previous tutorial and add the loadImages function and the preloader.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    var initialized = false;
    var images = [];
 
    // (...)
 
    // Initialize the game
    function init() {
        // Load images
        images = loadImages(["sprite1.png", "sprite2.png", "sprite3.png"]);
 
        // (...)
    }
 
    // Main loop
    function main(tframe) {
        // Request animation frames
        window.requestAnimationFrame(main);
 
        if (!initialized) {
            // Preloader
 
            // Clear the canvas
            context.clearRect(0, 0, canvas.width, canvas.height);
 
            // Draw the frame
            drawFrame();
 
            // Draw a progress bar
            var loadpercentage = loadcount/loadtotal;
            context.strokeStyle = "#ff8080";
            context.lineWidth=3;
            context.strokeRect(18.5, 0.5 + canvas.height - 51, canvas.width-37, 32);
            context.fillStyle = "#ff8080";
            context.fillRect(18.5, 0.5 + canvas.height - 51, loadpercentage*(canvas.width-37), 32);
 
            // Draw the progress text
            var loadtext = "Loaded " + loadcount + "/" + loadtotal + " images";
            context.fillStyle = "#000000";
            context.font = "16px Verdana";
            context.fillText(loadtext, 18, 0.5 + canvas.height - 63);
 
            if (preloaded) {
                // Add a delay for demonstration purposes
                setTimeout(function(){initialized = true;}, 1000);
            }
        } else {
            // Update and render the game
            update(tframe);
            render();
        }
    }

Below you can see the result of the preloader. Before the game starts, the preloader shows a progress bar which indicates the loading process of the images. During the preloader, the actual game is not being updated yet. Only after the images are loaded, the initialized variable becomes true and the normal render loop can continue.

HTML5 Preloader

Screenshot of the HTML5 Preloader

Bouncing Images Example

To conclude this tutorial, I have created a fully working example that loads a couple of images and draws them to the screen. The images bounce around the screen, after the preloader is done loading the images. The full source code is available on GitHub.