O'Reilly logo

HTML5 Canvas by Jeff Fulton, Steve Fulton

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Width, Height, Scale, and toDataURL() Revisited

In Chapter 1, we briefly discussed that you can set the width and height of the canvas, as well as the scale (style width and height) of the canvas display area, dynamically in code. We also showed you an example of using the Canvas object’s toDataURL() method to export a “screenshot” of the Canvas application. In this section, we will revisit those functions as they relate to Text Arranger 3.0.

Dynamically Resizing the Canvas

In the code we developed in this chapter, we created a reference to the Canvas object on the HTML page—with the id canvasOne—and used it to retrieve the 2D context of the Canvas object:

var theCanvas = document.getElementById("canvasOne");
var context = theCanvas.getContext("2d");

While the 2D context is very important because we used it to draw directly onto the canvas, we did not spend any time discussing the Canvas object itself. In this chapter, we use the width property of the Canvas object to center text on the canvas. However, the Canvas object also includes another property named height, and both of these properties can be used to dynamically resize the Canvas object on demand. Why would you want to do this? There could be many uses, such as:

  • Updating the canvas to the exact size of a loaded video object

  • Dynamically animating the canvas after the page is loaded

  • Other, more creative uses like the one we will experiment with next

Resizing the canvas on the fly is quite easy. To do it, simply set the width and height properties of the Canvas object, and then redraw the canvas contents:

Canvas.width = 600;
Canvas.height = 500;

The Canvas 2D API describes this function as a way to “scale” the canvas, but in practice, this does not appear to be true. Instead, the contents of the canvas are simply redrawn at the same size and same location on a larger canvas. Furthermore, if you don’t redraw the canvas content, it appears to be invalidated, blanking the canvas back to white. To properly scale the canvas, you need to use the CSS width and height attributes, as described in the next section. We discuss using a matrix transformation to scale the Canvas in both Chapters 2 and 4.

Dynamically resizing in Text Arranger

We will add the ability for the canvas to be resized at will, giving you a good example of how resizing works and what it does to your drawn content.

First, we will add a couple new range controls to the HTML <form>. As you might have already guessed, we really like this new HTML5 range control, so we’ve tried to find as many uses as possible for it—even though it’s only tangentially related to HTML5 Canvas.

We will give the controls the ids canvasWidth and canvasHeight:

Canvas Width:  <input type="range" id="canvasWidth"

  Canvas Height:
  <input type="range" id="canvasHeight"

Next, we add event listeners for the new form elements in the canvasApp() function:

formElement = document.getElementById("canvasWidth");
formElement.addEventListener('change', canvasWidthChanged, false);

formElement = document.getElementById("canvasHeight");
formElement.addEventListener('change', canvasHeightChanged, false);

Finally, we add the event handlers. Notice that we set the width and height of theCanvas (the variable we created that represents the Canvas object on screen) right inside these functions. We also need to make sure that we call drawScreen() in each function so that the canvas is redrawn on the newly resized area. If we did not do this, the canvas on the page would blank back to white:

function canvasWidthChanged(e) {
      var target = e.target;
      theCanvas.width = target.value;

function canvasHeightChanged(e) {
      var target =  e.target;
      theCanvas.height =  target.value;

We also need to change the way we draw the background for the application in the drawScreen() function so it supports a resized canvas. We do this by using the width and height attributes of theCanvas to create our background and bounding box:

context.fillStyle = '#ffffaa';
context.fillRect(0, 0, theCanvas.width, theCanvas.height);
context.strokeStyle = '#000000';
context.strokeRect(5,  5, theCanvas.width−10, theCanvas.height−10);

Dynamically Scaling the Canvas

Besides resizing the canvas using theCanvas.width and theCanvas.height attributes, you can also use CSS styles to change its scale. Unlike resizing, scaling takes the current canvas bitmapped area and resamples it to fit into the size specified by the width and height attributes of the CSS style. For example, to scale the canvas to a 400×400 area, you might use this CSS style:

style = "width: 400px; height:400px"

To update the style.width and style.height properties of the canvas in Text Arranger, we first create two more range controls in the HTML page:

Canvas Style Width:  <input type="range" id="canvasStyleWidth"

  Canvas Style Height:
  <input type="range" id="canvasStyleHeight"

Next, we set the event handler for each range control. However, this time we are using the same handler —canvasStyleSizeChanged()—for both:

formElement = document.getElementById("canvasStyleWidth");
formElement.addEventListener("change", canvasStyleSizeChanged, false);
formElement = document.getElementById("canvasStyleHeight");
formElement.addEventListener("change", canvasStyleSizeChanged, false);

In the event handler, we use the document.getElementById() method to get the values from both range controls. We then create a string that represents the style we want to set for the canvas:

"width:" + styleWidth.value + "px; height:" + styleHeight.value +"px;";

Finally, we use the setAttribute() method to set the “style”:

function canvasStyleSizeChanged(e) {

    var styleWidth = document.getElementById("canvasStyleWidth");
    var styleHeight = document.getElementById("canvasStyleHeight");
    var styleValue = "width:" + styleWidth.value + "px; height:" + 
        styleHeight.value +"px;";
    theCanvas.setAttribute("style", styleValue );


While trying to change theCanvas.width and theCanvas.height attributes, you might notice some oddities if you try to change the scale with CSS at the same time. It appears that once you change the scale with CSS, the width and height attributes update the canvas in relation to that scale, which might not be the effect you are expecting. Experiment with Text Arranger 3.0 to see how these different styles and attributes interact.

The toDataURL() Method of the Canvas Object

As we briefly explained in Chapter 1, the Canvas object also contains a method named toDataURL(), which returns a string representing the canvas’ image data. A call with no arguments will return a string of image data of MIME type image/png. If you supply the image/jpg as an argument, you can also supply a second argument between the numbers 0.0 and 1.0 that represents the quality/compression level of the image.

We are going to use toDataURL() to output the image data of the canvas into a <textarea> on our form, and then open a window to display the actual image. This is just a simple way to show that the function is working.

The first thing we do is create our last two form controls in HTML for Text Arranger. We start by creating a button with the id of createImageData that, when pressed, will create the image data with a call to an event handler named createImageDataPressed().

We also create a <textarea> named imageDataDisplay that will hold the text data of the image after the createImageData button is pressed:

<input type="button" id="createImageData" value="Create Image Data">

<textarea id="imageDataDisplay" rows=10 cols=30></textarea>

Next, we set up the event listener for the createImageData button:

formElement = document.getElementById("createImageData");
formElement.addEventListener('click', createImageDataPressed, false);

Then, in the createImageDataPressed() event handler, we call the toDataURL() method of the Canvas object (theCanvas), and set the value of the imageDataDisplay <textarea> to the data returned from toDataURL(). Finally, using the image data as the URL for the window, we call window.open(). When we do this, a window will pop open, displaying the actual image created from the canvas (see Figure 3-11). You can right-click and save this image, just like any other image displayed in an HTML page. Pretty cool, eh?

function createImageDataPressed(e) {

      var imageDataDisplay = document.getElementById('imageDataDisplay');
      imageDataDisplay.value = theCanvas.toDataURL();
      window.open(imageDataDisplay.value,"canvasImage","left=0,top=0,width=" + 
          theCanvas.width + ",height=" + theCanvas.height +
Canvas exported image with toDataURL()

Figure 3-11. Canvas exported image with toDataURL()

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required