Working with canvas – Some Background and Basics

Posted: March 23, 2009 Comments(4)

If I had to pick, I think I’d choose canvas as the single item I’m most excited about when it comes to “bleeding edge” advancements in front end. I’d still classify canvas as bleeding edge simply because it’s still building momentum and catching on in the general Web design population. Although it’s been around for some time, I still run into many designers who either haven’t heard of the element, or have heard of it, but don’t quite get it.

Some background on canvas

Something many people don’t know is that canvas was originally introduced by Apple to be used within WebKit. The original intent was to use the element in such environments as applications in Dashboard or new tools in Safari. After its implementation in WebKit, canvas was adopted by Gecko (the rendering engine most notably powering Firefox), and Opera. It was at that point canvas was standardized by the WHATWG. While canvas isn’t supported directly by Internet Explorer, the same functionality can be duplicated using a combination of VML and JavaScript. The canvas element is officially defined by the WHATWG as:

The canvas element represents a resolution-dependent bitmap canvas, which can be used for rendering graphs, game graphics, or other visual images on the fly.

Working with canvas

canvas is defined by a height and width, much like many other elements in HTML. A set of drawing functions are offered to JavaScript to allow for the creation of various shapes and other dynamically generated graphics.

To include the canvas element in your document, it’s a matter of simply including the tag with a few attributes:

<canvas id="my_canvas" width="300" height="200"></canvas>

width and height are the only two (optional) attributes of canvas, which can be defined as the snippet above, or using CSS/DOM properties. If no width and height attributes are defined, the canvas will default to 300px wide and 150px tall. You can also give your canvas an id and/or class, and you’re also able to define other style properties (e.g. margin).

The canvas element closely resembles an img element we’ve worked with since we made our first website. A big difference, however, is that canvas is not self-closing. This turns out to be a benefit, as we’re able to easily include alternate content for those browsers that don’t actively support canvas:

<canvas id="my_canvas" width="300" height="200">
	<img src="images/car.png" alt="Blue Honda Civic Si" />
</canvas>

While Apple’s original canvas implementation did not require a closing tag, Mozilla’s implementation does, so it will be in your best interest to use canvas as outlined above.

Including the element in your document can be compared to opening your sketchbook to a new page; you’re simply provided a surface on which to draw. The ability to draw is enabled through a scripting language such as JavaScript, and you’re given a toolset of functions to work with. This toolset is controlled by something called a rendering context, used to perform the manipulations you’re looking for. We’ll take a quick look at the 2D rendering context.

Drawing in 2D with canvas

To work with your newly implemented canvas element, you’re going to need to access the element using DOM methods. The first method we’ll look into is getContext. This method allows us to obtain the rendering method we’re looking to use, as well as its drawing functions we need. We’re able to pass one parameter to getContext: the context type.

var canvas = document.getElementById('my_canvas');
var context = canvas.getContext('2d');

Once we’ve identified our DOM node (line 1), we’re able to access our context using getContext (line 2). It’s important to remember graceful degradation at all times, and working with canvas is no exception. At this point, we can determine if we’ve got canvas support by checking to see if getContext is supported:

var canvas = document.getElementById('my_canvas');
if(canvas.getContext)
{
	var context = canvas.getContext('2d');
}
else
{
	// fallback (canvas is not supported)
}

Until this point, we haven’t been doing much in the way of exciting. In fact, we have yet to draw anything. If you’ve taken any computer science classes in the past, it’s very likely that drawing with canvas will heavily remind you of COMPSCI 201: Intermediate Programming with Java. The two dimensional rendering context provided by canvas makes available many similar, if not identical functions, to those provided in Java. For example, drawing a rectangle is accomplished by first defining a fillStyle, and then executing a fillRect to draw the shape on our canvas using the fillStyle previously defined:

function draw_rect()
{
	var canvas = document.getElementById('my_canvas');
	if(canvas.getContext)
	{
		var context = canvas.getContext('2d');
		context.fillStyle = "rgb(100,100,100)";
		context.fillRect(0, 0, 100, 100);
	}
	else
	{
		// fallback (canvas is not supported)
	}
}

View example

In addition to defining a fillStyle with RGB values, you can also incorporate RGBA values as well, which opens the door to even more exciting possibilities.

Some of the many uses for canvas

The canvas element gives Web designers a completely new avenue to explore. Some of the most widespread use seems to fall upon the creation of graphs, building animations, and in-browser gaming. It’s been said that canvas is going to not only enrich the Web browsing experience by providing a very lightweight, plugin-free environment, but also do its part to tackle the default decision to resort to Flash when trying to implement any sort of rich interaction with a document.

I’m really excited to see where canvas takes us over the next five years, as adoption is catching on quickly, and ingenious examples of what canvas is capable of are cropping up on a weekly basis. If you haven’t had the chance quite yet, check out Processing.js (which is just mind blowing), OCR and Neural Nets in JavaScript, Chrome Experiments, just to name a few examples of impressive implementations based on canvas. What are some of your favorite implementations?

Should there be enough interest, I’d like to walk through some of the more advanced functionality provided by canvas rendering contexts in subsequent parts of this ‘Working with canvas’ series. Hopefully it’s a subject a number of readers are interested in, but I’m most curious to see if that’s the case. Has canvas reached a point where you feel it will be a necessary part of your knowledge base?

Get my newsletter

Receive periodic updates right in the mail!

  • This field is for validation purposes and should be left unchanged.

Comments

  1. Thanks for the post! I’m one of the designers who “have heard of it, but don’t quite get it”.

    So i would be appreciated to read more about CANVAS and VML injection.

    Keep going on 🙂

  2. Great post. Just one slight suggestion. Rather than have the entirety of the JS inside an if statement, with an else right at the end, I’d do this at the beginning…

    if (!canvas.getContext) {
    return;
    }

    That way, at a glance, you know you’ve accounted for it, instead of having to scroll all the way to the end to see what the else statement is (or to confirm that indeed there is an else statement).

  3. @Ole: I’m glad you found it useful! Stay tuned for some more elaborate examples in the coming weeks.

    @Nathan Smith: Terrific suggestion, I have no idea why I didn’t implement the check in that way. It’s without a doubt cleaner and more straightforward, thanks very much for pointing it out!

Leave a Reply

Your email address will not be published. Required fields are marked *