Papa's Perspective

Working with the HTML5 Canvas: A 5-Minute Tutorial

Get started with this quick but informative guide (and sample code) from John Papa.

Sometimes you want to render a visual on the fly, or even animate it. Perhaps the visual is a complex path where the set of x,y coordinates dictate what to render. Or perhaps the visual is a graph whose coordinates are defined by data. For these scenarios and much more, the HTML5 canvas is ideal. The canvas allows you to draw objects, words, games and just about any other creative visuals you can think of in a Web browser. In short, the canvas tag provides a simple way to render on the client using JavaScript.

Table 1 describes some of the core canvas functions I'll use to draw lines in my example.

Function Description
arc() Renders an arc given an x,y coordinate for its center, a radius, starting and ending angles, and the direction to draw
beginPath() Indicates the beginning of a new path
lineCap Defines how to cap the ends of lines
lineJoin Defines how to join lines
lineTo() Draws a line from the current coordinates to a newly-provided coordinate
lineWidth() Width in pixels of the lines to be drawn
moveTo() Moves from the current coordinates to a newly-provided coordinate without drawing
stroke() Renders any un-rendered drawings
strokeStyle() Defines the color of the strokes to draw

Table 1 A quickstart table of core canvas functions.

Grab a Canvas and Its Context
The basics of the canvas can be demonstrated by looking at a fun example of rendering my name. First, I create a blank HTML page and add a canvas tag. I make the page 800 x 600 to leave plenty of room to draw. Once I add the variable to refer to the canvas element, and a context variable to get the 2D rendering context of the canvas (see Listing 1), I'm ready to start rendering to its context.

Define Your Canvas Settings
I want to draw some letters for my name, so I have to set up some ground rules to define the letter and line widths. In this case, they'll be variable and all other values will be calculated off these two values. This allows my lettering to be drawn larger or smaller at a reasonable scale. I also need to tell the canvas some basics, including the line width, how to join lines and how to cap the lines (such as round or square). All lines rendered on the canvas will now use these values:

context.lineWidth = lineWidth;
context.lineCap = "square";
context.lineJoin = "round";

Draw on the Canvas
Now it's time to start drawing the first letter in my name (John), so I tell the canvas I'm starting a path using the beginPath function. I want the letter "J" to be blue, so I set its strokeStyle property accordingly. It's easiest to break the letters up into their separate lines. For example, the "J" has two lines: the vertical line and a 180-degree arc on the bottom. I'll draw the vertical line first.

It's good to think of drawing as using a pen on paper, instead of coordinates on a canvas. When I pick my pen off the paper and move the pen to a new position, I'm using the moveTo function. When I draw with my pen pressed against paper, I'm using the lineTo function. So I can use the moveTo function to position the pen at the top of the J, and draw downward using the lineTo function, as shown here:

context.beginPath();
context.strokeStyle = "Blue";
context.moveTo(leftX + letterWidth, topY);
context.lineTo(leftX + letterWidth, bottomY - letterRadius - lineWidth);

I can continue to draw the bottom of the J by using the arc function. The first two parameters define the x and y coordinates for the center of the arc. The third parameter sets the radius of the arc. The next two parameters define the starting and ending angles. Notice the starting angle starts at zero and ends at Math.PI. This produces a half circle starting from the right and moving to the left. The sixth and final parameter defines that the arc moves clockwise. Now that the J is drawn, it's rendered using the stroke function, like so:

context.arc(leftX + letterWidth/2, lowercaseArcY, letterRadius, 0, Math.PI, false);
context.stroke();

You can use this same sequence to continue drawing more letters by changing the colors and moving the pen.

Experiment
The complete source code is available for download with this article. All property settings in the sample are calculated from the letter width and line width variables. This allows the letters to be drawn larger or smaller at a reasonable scale (within boundaries). Feel free to change the letterWidth and lineWidth properties to see some interesting effects such as overlapping letters.

You can use the HTML5 canvas to draw charts, graphics, data-driven diagrams or just to have fun. Its great performance makes the canvas ideal for drawing graphics-intensive apps that require rendering many objects, animating them and redrawing them repeatedly. But if you need to zoom in and out of your drawings, for activities such as drawings maps, scalable vector graphics might be a better option.

About the Author

John Papa is a Microsoft Regional Director and former Microsoft technical evangelist. Author of 100-plus articles and 10 books, he specializes in professional application development with Windows, HTML5, JavaScript, CSS, Silverlight, Windows Presentation Foundation, C#, .NET and SQL Server. Check out his online training with Pluralsight; find him at johnpapa.net and on Twitter at twitter.com/john_papa.

comments powered by Disqus

Featured

Subscribe on YouTube