Images

IE[a]

Firefox

Safari

Chrome

Opera

iPhone

Android

7.0+

3.0+

3.0+

3.0+

10.0+

1.0+

1.0+

[a] Internet Explorer support requires the third-party explorercanvas library.

Figure 4-12 shows an image of a cat displayed with the <img> element.

Cat with an <img> element

Figure 4-12. Cat with an <img> element

Figure 4-13 shows the same cat, drawn on a canvas.

Cat with a <canvas> element

Figure 4-13. Cat with a <canvas> element

The canvas drawing context defines several methods for drawing an image on a canvas:

  • drawImage(image, dx, dy) takes an image and draws it on the canvas. The given coordinates (dx, dy) will be the upper-left corner of the image. Coordinates (0, 0) would draw the image at the upper-left corner of the canvas.

  • drawImage(image, dx, dy, dw, dh) takes an image, scales it to a width of dw and a height of dh, and draws it on the canvas at coordinates (dx, dy).

  • drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) takes an image, clips it to the rectangle (sx, sy, sw, sh), scales it to dimensions (dw, dh), and draws it on the canvas at coordinates (dx, dy).

The HTML5 specification explains the drawImage() parameters:

The source rectangle is the rectangle [within the source image] whose corners are the four points (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh).

The destination rectangle is the rectangle [within the canvas] whose corners are the four points (dx, dy), (dx+dw, dy), (dx+dw, dy+dh), (dx, dy+dh).

Figure 4-14 gives a visual representation of these parameters.

To draw an image on a canvas, you need an image. The image can be an existing <img> element, or you can create an Image object with JavaScript. Either way, you need to ensure that the image is fully loaded before you can draw it on the canvas.

If you’re using an existing <img> element, you can safely draw it on the canvas during the window.onload event:

<img id="cat" src="images/cat.png" alt="sleeping cat" width="177" height="113">
<canvas id="e" width="177" height="113"></canvas>
<script>
window.onload = function() {
  var canvas = document.getElementById("e");
  var context = canvas.getContext("2d");
  var cat = document.getElementById("cat");
  context.drawImage(cat, 0, 0);
};
</script>
How drawImage() maps an image to a canvas

Figure 4-14. How drawImage() maps an image to a canvas

If you’re creating the image object entirely in JavaScript, you can safely draw the image on the canvas during the Image.onload event:

<canvas id="e" width="177" height="113"></canvas>
<script>
  var canvas = document.getElementById("e");
  var context = canvas.getContext("2d");
  var cat = new Image();
  cat.src = "images/cat.png";
  cat.onload = function() {
    context.drawImage(cat, 0, 0);
  };
</script>

The optional third and fourth parameters to the drawImage() method control image scaling. Figure 4-15 shows the same image of a cat, scaled to half its width and height and drawn repeatedly at different coordinates within a single canvas:

Here is the script that produces the “multicat” effect:

cat.onload = function() {
  for (var x = 0, y = 0;
       x < 500 && y < 375;
       x += 50, y += 37) {   
    context.drawImage(cat, x, y, 88, 56);
  }
};

All this effort raises a legitimate question: why would you want to draw an image on a canvas in the first place? What does the extra complexity buy you over an <img> element and some CSS rules? Even the “multicat” effect could be replicated with 10 overlapping <img> elements.

The simple answer is that you’d do this for the same reason you might want to draw text on a canvas (see Text). Our canvas coordinates diagram (see Canvas Coordinates) included text, lines, and shapes; the text-on-a-canvas element was just one part of a larger work. A more complex diagram could easily use drawImage() to include icons, sprites, or other graphics.

Multicat!

Figure 4-15. Multicat!

Get HTML5: Up and Running now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.