A Programmer's Guide to Canvas
Written by Ian Elliot   
Article Index
A Programmer's Guide to Canvas
Active and Passive

The HTML5 canvas object provides bitmap graphics to JavaScript. For a programmer's viewpoint of how it all works read on.


Now available as a paperback or ebook from Amazon.

JavaScript Bitmap Graphics
With Canvas




  1. JavaScript Graphics
  2. Getting Started With Canvas
  3. Drawing Paths
      Extract: Basic Paths 
      Extract: Bezier Curves 
  4. Stroke and Fill
      Extract: Stroke Properties 
      Extract: Fill and Holes **NEW!
  5. Transformations
      Extract: Transformations 
  6. Text
      Extract: Text, Typography & SVG 
      Extract: Unicode 
  7. Clipping, Compositing and Effects
      Extract: Clipping & Basic Compositing 
  8. Generating Bitmaps
      Extract:  Introduction To Bitmaps 
  9. WebWorkers & OffscreenCanvas
      Extract: OffscreenCanvas
  10. Bit Manipulation In JavaScript
  11. Typed Arrays
  12. Files, blobs, URLs & Fetch
      Extract: Blobs & Files
      Extract: Read/Writing Local Files 
  13. Image Processing
      Extract: ImageData
      Extract: The Filter API
  14. 3D WebGL
  15. 2D WebGL
    Extract: WebGL Convolutions 






As long as you are working with a modern browser you have two options, at least, when creating graphics in JavaScript -

a vector drawing option - SVG


a bitmap drawing option - Canvas.

Although SVG has its advantages many applications and many programmers are much happier working with bitmaps and this means that Canvas is your general purpose graphics element. 

You can use Canvas to create graphics applications, animation and a completely custom UI if that's what you are intereseted in. It also supports 3D graphics by way of WebGL but this is a topic in its own right and in this chapter we look at 2D Canvas use. 

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 more complicated and perhaps best used via a framework - 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. This is exactly the same as when you use an <img> tag - the bitmap has a physical size, so many pixels by so many and the heigh and width you specify allocates the space used to display the bitmap.

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 - with scaling applied if necessary. 

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"

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 can 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);

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);

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(



Last Updated ( Thursday, 24 January 2019 )