HTML5 Canvas Resize On The Fly, In An HTML Page

I’ve been playing around a lot with the HTML5 Canvas lately, and I discovered some very interesting things that about the size of Canvas as displayed on an HTML page.

The best way to show these is to show a demo of what I’m talking about first.  Here is a link to the demo:
http://www.8bitrocket.com/wp-content/uploads/2010/08/CanvasResizeBlog.html

Note: This demo works best in Google ChromeThe Range controls listed below will not appear in Firefox…yet.

What you will notice on the demo page is a 500×300 Canvas with the text “Text Wrangler” applied to to it.  Below the Canavs are 4 HTML form controls:

  1. A Text box to change the text
  2. An HTML5 Range Control to change the size of the text
  3. An HTML5 Range Control to change the width of the Canvas
  4. An HTML5 Range Control to change the height of the Canvas

Changing the size of the text is a no-brainer.  I added that to show that the Canvas itself could be manipulated with a form control on an HTML page.   However, the range controls for the width and the height of the Canvas are what I’m concentrating on here.  If you play with them you will notice that the width and size of the Canvas can be changed on a page dynamically.  I coded the text to stay in the middle of the Canvas, no matter what the size, with this code:

[cc lang=”javascript” width=”550″]
var metrics = context.measureText(message)
var textWidth = metrics.width;
var xPosition = (theCanvas.width/2 – textWidth/2);
var yPosition = (theCanvas.height/2);

[/cc]

The measureText() method is native to the Canvas context object.  It only has one property, width.    Since text has a default baseline of “middle”, you can center text vertically by placing it at the middle pixel on the screen.  However, text default to a horizontal alignment of “start”, which means you need to either set it to “center” or subtract 1/2 the width of the text to get a proper horizontal center at the midpoint of the Canvas.

Now, if you play with the range controls to chnage the width and the height of the Canvas, notice how it interplays with rest of the page.   The form elements move up and down the page as the the height is changed.   The text on the Canvas stays the same scale and centered, no matter how big or small the Canvas might be.   This appears to be the opposite of what is specified in the Canvas API:

The intrinsic dimensions of the canvas interface element equal the size of the coordinate space, with the numbers interpreted in CSS pixels. During rendering, the image must be scaled to fit this layout size.

The image does not appear to scale when the Canvas is resized.  In fact, it simply allows for more of the Canvas to be viewed.  I saw the same effect in Safari.  It is possible that I’m reading the API spec wrong too.  No matter, the cool part is that the Canvas can completely redisplay itself, on the fly, with updated width and height without reloading the page.

It appears to me that the HTML5 Canvas is built to allow for the same types of free-flowing liquid user interfaces that can be created in Flash using “noscale” and JavaScript, but with the added feature of being able to resize the entire Canvas on the fly in real-time.  I’ve NEVER seen that done with Flash.  I’m not saying you can’t do it, I’ve just never seen it done before.

Here are some code highlights:

The HTML5 form controls below the Canvas interact with the Canvas by listening for events only.  When any control is changed, event handlers are used to capture that change and then render it on the Canvas.

[cc lang=”javascript” width=”550″]
var context = theCanvas.getContext(‘2d’);
var formElement = document.getElementById(“textBox”);
formElement.addEventListener(‘change’, textBoxChanged, false);

formElement = document.getElementById(“textSize”);
formElement.addEventListener(‘change’, textSizeChanged, false);

formElement = document.getElementById(“canvasWidth”)
formElement.addEventListener(‘change’, canvasWidthChanged, false);

formElement = document.getElementById(“canvasHeight”)
formElement.addEventListener(‘change’, canvasHeightChanged, false);

[/cc]

Here are the Event Handlers functions.  Notice that to change the width and height of the Canvas, we simply update the the width and height attributes of the Canvas object. (Note: theCanvas is the id of the the Canvas object in the HTML page)

[cc lang=”javascript” width=”550″]
function textBoxChanged(e) {
var target = e.target;
message = target.value;
drawScreen();
}

function textSizeChanged(e) {
var target = e.target;
fontSize = target.value;
drawScreen();
}

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

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

[/cc]

Here is the code in the drawScreen() function that renders the text based on the current width and height of the Canvas.

[cc lang=”javascript” width=”550″]
var metrics = context.measureText(message)
var textWidth = metrics.width;
var xPosition = (theCanvas.width/2 – textWidth/2);
var yPosition = (theCanvas.height/2);
var tempColor = “#000000”;
context.fillStyle = tempColor;
context.fillText ( message, xPosition ,yPosition);
context.strokeStyle = “#FF0000”;
context.strokeText ( message, xPosition,yPosition);
[/cc]

Check out the demo again:

http://www.8bitrocket.com/wp-content/uploads/2010/08/CanvasResizeBlog.html

One comment

  1. What if that canvas had a background-image. How would you also resize that?

Leave a Reply