Blake Smith

create. code. learn.


html5: learning the canvas by iteration

I’ve been absolutely amazed at the creative and inspiring experiments that people have been creating using the HTML5 Canvas and other new HTML5 technologies. These are taking a shot at proprietary rich media technologies such as Flash and Silverlight. I’m very excited about this. I’m excited that I can develop using these methods without having to buy in to any proprietary tools or be tied to any operating system.

So I decided to do a one day spike with the HTML5 canvas. My goal was to make a toy demonstration that did some basic animation. I took an iterative approach to learning: I tried to bite off and learn small chunks with the intent of building upon them in future iterations. I used the Mozilla HTML5 Canvas Tutorial to learn some of the techniques. Here’s what I accomplished:

iteration 1: draw something

In iteration 1, I wanted to get a canvas setup, and draw something to it. Very basic I know, but you have to start somewhere! Step one was to recreate this example.

View this example

Iteration 1

So far so good. We’ve drawn something, now let’s give it some movement.

iteration 2: make those shapes dance

In iteration 2, I wanted to make a single rectangle that rotated in place. A very simple animation. Using the translate and rotate techniques, I was able to accomplish this.

View this example

Iteration 2

Cool, we’ve got some basic movement. The biggest hurdle in this iteration was understanding the alternate animation technique. I was expecting some kind of rectangle method that would skew rectangle itself. Instead, the HTML5 canvas uses the save() and restore() methods to move the canvas itself, and then draw. So in each frame of the animation, you’re actually rotating the canvas, drawing the shape, and then reverting the canvas back to normal. Think of it like how they filmed the old Star Wars: Instead of moving the space ships around the camera, they got a camera that could move around the space ships.

iteration 3: objectify and multiply

So we’ve got a spinning rectangle, but if I wanted to create 100 spinning rectangles it’s not organized enough. So this iteration was spent making the rectangle into an object. Then it’s simply a matter of making more objects.

View this example

Iteration 3

Awesome! So now we’ve got a rectangle that’s encapsulated as a javascript object. In our main loop, we simply iterate over an array of all drawable assets and tell each one to draw. Right now, we’re just manually adding each rectangle to the array list. This technique will lead us into iteration 4, where we can use a function to generate rectangles.

iteration 4: generate some happiness

This is where stuff starts to get cool. Instead of populating our array of drawable shapes manually, let’s use a function to create the assets.

View this example

Iteration 4

So now the generateShapes() method is generating 100 different rectangle objects and adding them to the allShapes array for drawing. I also introduced a bit of randomness when the method is generating each rectangle. Each one is placed in a x,y coordinate somewhere on the canvas, with a random red value rotating at a random angle each frame.

iteration 5: add some pizazz

This is a very simply aesthetic iteration. I added in the ability for each rectangle to randomly rotate clockwise or counter-clockwise, as well as have a random rgb value and random opacity level.

View this example

Iteration 5

Fairly straight-forward stuff. Rotation direction is a simple true/false boolean, rgb is randomly generated by selecting a random number between 0 and 255 for the red, green, and blue values.

iteration 6: let there be snow

Everything’s already looking pretty good, but let’s add the icing on the cake. Let’s make each rectangle fall at a random speed from the top of the screen like snow. When a rectangle falls out of the visible area, remove it from the allShapes array and add a new one that starts at the top.

View this example

Iteration 6

This was by far the longest iteration. I wanted to make it so that I could turn rectangle falling on and off. Managing the resource array took some effort as well. I came up with a scheme to remove the assets from the allShapes array, but with a flicker. Eventually I devised a method that used a seperate setInterval ‘thread’ to check for stale objects every second. This has the advantage of not interupting the draw ‘thread’ when it’s drawing (the flicker was caused when assets were being removed in the middle of drawing; interupting fast and continuous drawing is a no-no).

go forth and create

In just part of a day, I was able to get some of this neat stuff created using the HTML5 canvas. Using basic iteration I was able to step my way into learning just some of the building blocks of the canvas. I hope you feel inspired to create some awesome canvas art. If you want to checkout the code in more detail, I’ve put it up on github.

about the author

Blake Smith is a Principal Software Engineer at Sprout Social.