More fun with the HTML5 canvas

HTML5 canvas - not as confusing as prototypes

Oh go on then. Here’s another canvas animation. It’s pretty simplistic but so far it’s just a work in progress of something more fun. And after that, some thoughts on what comes next on a technical level.


Just stare at it for a few seconds and then try to write. Ooh, swirly.

The thing that’s put me off learning Javascript beyond the bare minimum has been how prototyping and the object model works – i.e. strange and scary for newcomers. But I had to bite the bullet here and use both, and while it is indeed strange it’s not that scary any more. I’ll not go into detail here since there are any number of tutorials on the internet but I’ll finish with this – it’s really not as bad as I thought1)Still weird though..

Timing is everything

One thing I’m having to start thinking about is the timing. There are two things controlling the animation speed here – the amount by which each band of circles gets rotated each frame, and how frequent the frames are. Increasing the frame frequency while reducing the step makes for a smoother animation but at the cost of processing requirements. Not a real consideration here since we’re only rendering a few hundred primitive shapes and the code can keep up with the timer easily enough.

Once things start to get more complicated though I’ll need to start looking at a real rendering loop. Right now the circles move by a fixed amount each frame. If the framerate remains steady – the computer isn’t doing anything else and your browser isn’t in the process of falling over – then that’s fine. But if the timer can’t fire as often as you want, or – more likely – your update code takes longer than the time available – you start to drift.

To get an idea of this, imagine you have a timer set at an interval of 1000 – one second. Each frame you increment a counter and write it to screen. That will be a fair approximation of the number of seconds the program has been running and barring something strange happening your counter won’t be too far off a stopwatch.

Now imagine that you’re doing something crazy slow inside each frame. You’re downloading an image from the internet to show that second. Now, although your timer is doing it’s best to fire every second, it’s having to wait for your download to finish, so let’s say that it only gets to fire every 1.2 seconds. In six seconds you’ve only drawn five frames. After a minute your timer is still showing “50seconds.png” Not so great.

So what to do? Unfortunately you have to throw your neat and easy assumptions out of the window. No more expecting that only (and exactly) 10ms has elapsed since the last frame. No more knowing that your bullet moves exactly 60 pixels to the right.

Now you have to design your animations and update cycles to work on velocity. Not pixels per frame, but pixels per millisecond. Go back to the perfect case: 10ms equals 60 pixels. It doesn’t take a rocket scientist to work out that this means your bullet is travelling at 6 pixels per ms. So keep track of the time elapsed since you last drew a frame and use that to update your objects.

No:

bullet.X += bullet.speed;

Yes:

time = elapsedTimeSinceLastFrame(); // Here magic happens
distance = bullet.speed * time;
bullet.X += distance; // Pew pew

Going back to our counter example, it would obviously make more sense to use the system timer to find out what second you’re currently on and download the image for that. So our counter example is something of a counter-example, but that’s just how things work out I guess. Stick with bullets is the moral here. Essentially you have to design your animations to have a logical state decoupled from the rendering state. Things should be drawn where they should be regardless of how fast the loop, and should update their state based on time elapsed, not on frames elapsed.

Now, I’m a long way from needing to worry about that sort of thing here, but regardless, watch this space for the finished version once I’ve figured out the maths and the timings…


Feet   [ + ]

1. Still weird though.

Leave a Reply

Post Navigation