A Programmer's Guide to Canvas
Written by Ian Elliot   
Article Index
A Programmer's Guide to Canvas
Stacks of states
Active and passive view

The HTML5 canvas object introduces bitmap graphics to JavaScript, something that has been missing for far too long. For a programmer's viewpoint of how it all works read on.

 

It never rains but it pours...

For ages the state of general graphics in browsers was difficult. You had a choice of two vector formats and basically you needed to rely on plug-ins to make either work across browsers. Now we have SVG and Canvas as standard in HTML5. So not only do we have a vector drawing option - SVG - but a bitmap drawing option - Canvas.

In fact Canvas is not only the newer of the two facilities it is also a more general image processing facility and as such deserves a more careful examination. There are lots of introductions to Canvas for beginning JavaScript programmers so let's take a slightly higher level view of the Canvas object - i.e. Canvas for programmers.

A 2D drawing context

The Canvas object is essentially a bitmap drawing surface. (If you want vector drawing then you need to look at SVG.) As such the Canvas object provides a drawing context which specifies how the bitmap will be drawn. At the moment there are two types of drawing context, a 2D one and a 3D one. The 3D drawing context is still slightly experimental - see Getting started with WebGL - and so we will concentrate on the 2D context.

Creating a drawing context is a two step process.

First you have to create a canvas object and use its getContext("type") to retrieve a CanvasRenderingContext object of the specified type. Once you have the drawing context you can use it methods and properties to draw on the surface.

The 2D drawing surface has its origin (0,0) at the top left hand corner.  The x axis increases to the right and y values increase going down the page. The size of the drawing surface is specified as the height and width parameters in pixels. All drawing commands use pixel co-ordinates but notice that fractional co-ordinates can be used and these shade pixels according to their proximity ot the location - i.e. anti aliasing techniques are used.

There is a subtle point to take note of in that the canvas object also has a Style ,height and width. The style height and width, if specified set the size that the canvas will be displayed at. The height and width properties specify the number of pixels in the rendering surface and if you specify a Style size the pixels are scaled to fit.

In short think of the width and height as specifying the size of the bitmap in pixels and the Style width and height as the space that it will be displayed in.

Any drawing operation that specifies pixels outside of the canvas area are simply clipped to fit.

Creating a canvas

So to create a canvas ready for use the usual method is to embed a <canvas> tag where you want it to appear:

<canvas id="Canvas" 
width="300" height="300"
style="height:600px;width:600px;">
</canvas>

This creates a 300x300 pixel canvas and allocates it a 600x600 display area - each pixel in the bitmap will be scaled to 4 pixels in the page. Of course in most cases we leave the style display size unspecified and then the display area is set equal to the pixel size.

The usual method of getting the drawing context is to use the DOM to retrieve the canvas object and then call the getContext method:

var c = document.getElementById("Canvas");
var ctx = c.getContext("2d");

Once you have the drawing context you can get on with using it via its drawing methods and attributes.

For example to draw a rectangle:

ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(10, 10, 55, 50);

Dynamic canvas creation

You can work with the canvas object completely in code if you want to.  First create the canvas object and set its size:

var c = document.createElement("canvas");
c.width = "500";
c.height = "500";

You can now draw on the bitmap but it wont actually be displayed until you add the canvas object to the DOM, for example:

var ctx = c.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(10, 10, 100, 50);
document.body.appendChild(c);

Notice that this approach allows you to work with a canvas behind the scenes and only show it when you are ready, if ever.

This dynamic approach is so useful that it is worth defining a function to create a canvas:

function createCanvas(h,w){
var c = document.createElement("canvas");
c.width = w;
c.height = h;
return c;
}

WIth this function our program now reads:

var c=createCanvas(100,100);
var ctx = c.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(10, 10, 100, 50);
document.body.appendChild(c);

If you do want to display the canvas as soon as it is created you can use something like:

var c=document.body.appendChild(
createCanvas(100,50));

and if you never want to refer to the canvas object again you could even write:

var ctx =document.body.appendChild(
 createCanvas(100,50)).getContext("2d");

Paths

In general the drawing methods work by creating a path which you can then fill or stroke (draw as an outline). 

You start a path using the beginPath() method or simply moveTo(x,y). There are various line drawing commands such as lineTo(x,y) and once you have a path completed you can render it using the stroke() and/or fill(). The path is drawn using the current set of drawing attributes - lineWidth, fillStyle and so on.

There are also the fillRect and strokeRec methods which can be used as a shortcut to a path and drawing it.



Last Updated ( Wednesday, 08 August 2012 )
 
 

   
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.