This is the first article in a series that will bring you up to speed with HTML5 canvas, the plugin-less drawing functionality built into modern browsers. In this introductory article, I'll show you how to access the canvas element, draw shapes, change colours, and erase things. It's a whistle-stop tour of the basics of this amazing new Web technology.
Prefer a Video Tutorial?
Change the resolution to 720 for a clearer picture.
Subscribe to our YouTube page to watch all of the video tutorials!
The series will be an exciting ride, and one that I hope you enjoy. I'm assuming that you're already comfortable with JavaScript, but have little to no experience with canvas. Even if you're new to JavaScript, don't fret, as you'll still learn something from these articles.
Introducing the Canvas Element
Using the canvas element is dead easy.
When you think of canvas, you probably think about the new HTML5 canvas
element. Technically, this is only one half of the story, but let's forget about that for now. The canvas
element is the public face of this fancy new feature of the browser.
Using the canvas
element is dead easy; it's one simple HTML tag, with a defined width and height.
<canvas width="500" height="500"> <!-- Insert fallback content here --> </canvas>
This doesn't do much yet. In fact, all it does is insert a transparent canvas on your page. The content inside of the canvas
element is fallback content, which will only display if a browser doesn't support canvas.
Browser support
Browser support for canvas is pretty amazing.
It's important to point out that the browser support for canvas is pretty amazing. Every modern browser supports it, including the latest Internet Explorer.
- Internet Explorer (9.0+)
- Safari (3.0+)
- Firefox (3.0+),
- Chrome (3.0+)
- Opera (10.0+)
- iOS (1.0+)
- Android (1.0+)
Interestingly, you can use some canvas functionality in Internet Explorer version 8 and below, via the ExplorerCanvas plugin.
Canvas dimensions
One key lesson that I learnt with canvas is that you have to explicitly set the width
and height
attributes of the canvas
element when defining its dimensions. Using CSS to set the width and height will effectively cause the canvas to scale up (or down) to that size. There is a logical reason behind this; it's to do with the canvas
element being a container for something called the 2d rendering context. However, it's just important to know that using CSS to set the canvas dimensions will have an odd effect.
Discovering the 2d Rendering Context
I mentioned in the last section that the canvas
element is only one half of the story. The other half is the 2d rendering context; the part of canvas that lets you do the cool stuff that you can actually see.
Let me make one thing completely clear: when you use canvas, you're not drawing on the canvas
element itself. Instead, you're actually drawing on the 2d rendering context, which you're accessing through the canvas
element via the JavaScript API. It doesn't really matter in the grand scheme of things, but it's useful to know.
Coordinate system
If you've used any 2d graphics programming languages before (ActionScript, Processing, etc), then you'll know all about screen-based coordinate systems. The 2d rendering context in canvas is no different; it uses a standard Cartesian coordinate system, with the origin point (0, 0) at the top left. Moving to the right will increase the value of the x axis, while moving downward will increase the value of the y axis. It's pretty straightforward.
One unit in the coordinate system is equal to one pixel on the screen (in the majority of cases).
Accessing the 2d rendering context
To actually use the 2d rendering context, you'll need to use the JavaScript API. The part of the API that you want to use is the getContext
method, like so:
<!DOCTYPE html> <html> <head> <title>Canvas from scratch</title> <meta charset="utf-8"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script> $(document).ready(function() { var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); }); </script> </head> <body> <canvas id="myCanvas" width="500" height="500"> <!-- Insert fallback content here --> </canvas> </body> </html>
Note: you're using jQuery here, but only for checking when the DOM is ready. Feel free to use your favorite JavaScript library instead, or place the code at the bottom of the document.
As a result of calling getContext
, the ctx
variable will now contain a reference to the 2d rendering context. This means that you now have everything in place to actually start drawing onto the canvas. The fun part!
Drawing Rectangles
Now that you have access to the 2d rendering context, you're able to start calling the drawing methods of the API. One of the most basic is fillRect
, which draws a rectangle that's filled in a particular colour (black by default).
Add the following code underneath the ctx
variable from earlier:
ctx.fillRect(50, 50, 100, 100);
This will draw a black square that is set slightly away from the left and top edges of the canvas, like so:
You've just drawn your first shape using HTML5 canvas. Feels good, right?
Note: You'll notice that you're using the rectangle method of the JavaScript API to draw squares. This is because there is no methods in canvas to draw squares directly, simple because squares are rectangles (they have four sides with right angles between them).
There are four arguments in a call to fillRect:
- The first is the x position of the origin point (the top left).
- The second is the y position of the origin point.
- The third is the width.
- And the forth is the height.
Written is pseudocode, fillRect
would look like this:
ctx.fillRect(x, y, width, height);
The cool thing is that you're not limited to just filled rectangles. Nope. You can also draw stroked rectangles; that is, rectangles with an outline around them. To to that you can use the strokeRect
method of the JavaScript API, like so:
ctx.strokeRect(50, 50, 100, 100);
It uses exactly the same arguments as fillRect
, and the result will be a lovely outline of a square:
Simple. Elegant. Easy. That really sums up canvas. All the methods are straightforward when looked at individually, but when used together they allow you to draw some pretty amazing things.
Drawing Paths
Aside from rectangles (the only shapes that can be drawn with a single API method), you have paths. Paths allow you to draw lines, both straight the curved, that can be combined to create quite complex shapes.
Drawing a simple path requires the use of a few new API methods:
-
beginPath
starts a new path. -
moveTo
moves the point that the path is drawn from. -
lineTo
draws a straight path to this point from the point defined in moveTo, or the point from the last call to lineTo. -
closePath
closes the path by connecting the last point to the starting point. -
fill
fills the path with a colour. -
stroke
outlines the path.
Try the following code:
ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(50, 250); ctx.lineTo(250, 250); ctx.closePath(); ctx.fill();
Which will draw a triangle path, and fill it:
You can use the same concept to draw any other shape that you want. The second article in this series will cover more advanced paths in canvas, like arcs (to create circles), and Bezier paths (to create cool curvy lines).
The important thing to remember right now is that paths are pretty much the only way to draw something more complicated than a rectangle.
Changing Colour
So far, everything that you've drawn has been filled or stroked in black. How exciting! Fortunately, there are a couple of properties within the JavaScript API that let you change the colour of the shapes that you're drawing. These properties are fillStyle
and strokeStyle
.
They're both pretty self explanatory, so let's jump in and change the fill colour of a rectangle:
ctx.fillStyle = "rgb(255, 0, 0)"; ctx.fillRect(50, 50, 100, 100);
This will give you a nice red square, like so:
Or, you could change the stoke colour of a rectangle:
ctx.strokeStyle = "rgb(255, 0, 0)"; ctx.strokeRect(50, 50, 100, 100);
Which will give you a square with a red outline:
The beauty of fillStyle
and strokeStyle
is that they both accept normal CSS colour values. That means you can use RGB, RGBA, HSA, colour words (eg. "red"), and hexadecimal values.
It's worth pointing that changing the colour in canvas won't affect anything that has already been drawn. For example, if you draw a black rectangle, then change the fill style to red, then draw another rectangle; the first rectangle will still be black.
Changing Line Width
Aside from changing colour, you can also change the width of a stroked outline. To do this you can use the lineWidth
property of the JavaScript API.
Using the code from the previous example, you can change the width of the outline:
ctx.lineWidth = 20; ctx.strokeStyle = "rgb(255, 0, 0)"; ctx.strokeRect(50, 50, 100, 100);
Which will give you a beautiful and chunky red stroke:
The same concept works for paths as well. For example, you can change the triangle from earlier to have a thicker outline:
ctx.lineWidth = 20; ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(50, 250); ctx.lineTo(250, 250); ctx.closePath(); ctx.stroke();
Which will give you an incredibly exciting chunky triangle:
There are also some other features of the JavaScript API that let you change the way lines are drawn. For example, lineCap
changes the way the end of a line looks, and lineJoin
changes the way the corners in a line look. You should definitely check out these features (and more) in the canvas specification.
Erasing the Canvas
The last thing that I want to teach you is how to erase the canvas. You've learnt how to draw shapes, but not how to actually get rid of them, which can be pretty darn useful.
Fortunately, erasing the canvas is easy; you just need one method from the JavaScript API. That method is clearRect
, and its job is to make every pixel within the rectangle transparent.
In this article, the canvas is 500 pixels wide, and 500 pixels tall, so you could easily erase the entire canvas by calling clearRect
like so:
ctx.fillRect(50, 50, 100, 100); ctx.clearRect(0, 0, 500, 500);
There's no use showing you a screenshot of this, because if it worked you should see absolutely nothing. The filled rectangle is actually being drawn, but it's instantly being cleared afterward, so you don't get to see it.
Note: The arguments in clearRect
are the same as fillRect
; x, y, width and height.
If you're not sure of the width and height of the canvas, you can also erase it like so:
ctx.clearRect(0, 0, canvas.width, canvas.height);
This uses the width
and height
properties of the canvas
element itself, which is incredibly useful and a much better way of doing things.
Erasing a small section of the canvas
You don't have to erase the entire canvas if you don't want to. You can quite easily erase just a small portion instead. For example, imagine you had a black square drawn next to a red square:
ctx.fillRect(50, 50, 100, 100); ctx.fillStyle = "rgb(255, 0, 0)"; ctx.fillRect(200, 50, 100, 100);
Which would normally look like this:
You could erase the black square and leave the red square intact by adding a call to clearRect
underneath:
ctx.clearRect(50, 50, 100, 100);
Notice how this call to clearRect defines a position and size that is the same as the black square. This basically means that it will only change the pixels in the area of the square to transparent black (erasing them):
Pretty nifty, isn't it? Erasing the canvas is not something that you'll use much with static drawings, but it's something that you'll be using a lot of when you learn how to animate later in this series.
Wrapping Things Up
Canvas is easy to use, quick to learn, and dead powerful when you push it to the limits.
So, as I hope you can see, canvas is a particularly potent new part of the browser. It allows you to create graphics, using code, and without using a single plugin. It's easy to use, it's quick to learn, and it's dead powerful when you push it to the limits.
In the next article, you'll be looking at some of the more advanced features of canvas, like drawing circles, curved paths, and something called the drawing state. And if that isn't enough, later on in the series you'll be looking at how to transform drawings (like rotation and scale), how to manipulate images, and ending with a look at how to animate. It's going to be very exciting stuff, trust me.
For now, I hope that I've given you enough to whet your appetite for canvas and to go out and learn more about it. Canvas is a fantastic technology that's really worth understanding, even if you don't plan to use it right away.
Comments