Hello, today I will show you how to make simple animations in the canvas element.
We will start with one of the simplest examples we saw last week, section 3.2, the one with the live coding video that showed how to draw a red rectangle.
So I'm going to start from this example.
Okay.
I'm just making a clone so that I'm not going to break anything...
And here you can see that we just had an init function that was called when the page is loaded, that just got the canvas object, the context from the canvas, and drew something, in our case it was a small red rectangle.
In order to perform animations... it's a very straightforward process: you've got to clear the canvas, draw shapes, move the shapes and do it again.
So I'm going just to call it "animate"... this function, animate, so it does exactly the same thing...
And I will first clear the canvas.
So, we saw last week how to clear the canvas using the clearRect() method. context dot clear rect, zero, zero - top left corner - canvas dot width, canvas dot height.
Like that, instead of just drawing the red rectangle, we are clearing the canvas and then we are drawing in the canvas.
So the trick consists in calling that repeatedly.
One of the most ancient method for doing that is to use setInterval.
I saw that some students in week 3 used setInterval for doing small animations.
This is not the recommended way today, to do smooth animation.
Anyway, it can be useful for simple cases.
In this video I'm going to show the different methods.
setInterval works like that: the first parameter is the name of the function, and the second parameter is the interval of time in milliseconds between consecutive calls to this function.
So if I put 1000, that means: each second, please, call animate().
You don't see any difference here because the coordinates, and the width and the height of the rectangle are the same, they do not change in time.
I change that with 100 + Math.random() that gives a number between 0 and 1, I multiply this by 10.
In that case... okay...okay... like that! We will have a rectangle that is moving here, and... okay, I made a mistake here... you can see that each second, the canvas is moving.
I can do that 10 times per second, and you will see that the canvas is moving... so this is how we do animation.
If we want the '*rectangle*' to move, or have some kind of behavior, we can use variables.
I'm using a global variable here... rectangleX, and if I use rectangleX here, in that case, the rectangle is drawn at (0, 0).
The third step I talked about earlier in this video, is "move the shapes".
So, in order to move the shapes we can just increment..., for example... like that we've got a moving rectangle! This is the basic principle of animation.
Let's see the different methods to do that.
With setInterval the problem is that if the code inside here takes too long, and if the interval is too short, the animation will be interrupted.
This is the first disadvantage of this method.
The second disadvantage is that the interval here is not really accurate.
We will not have a perfect animation that is performed each 100 milliseconds.
It may vary, but vary quite too much for writing professional video games or doing smooth animation.
The second method, that was recommended in the old times before HTML5, was to use setTimeout. setTimeout is a little bit different: it takes the function you want to call as a first parameter, the second parameter is a delay... 100 milliseconds before calling animate.
In that case it will draw the rectangle only once, and if you want to do an animation, you must call it at the end of the animation loop.
Call again.... ok. You've got the animation.
It's different from setInterval because it just says "ok, I would like this function to be called after 100 milliseconds." If the instructions here takes too long, it will just be late, but the animation will not be interrupted.
The last, and most up-to-date way to do animation is to use the brand new requestAnimationFrame.
The name of the function is ... just very clear: "please I want the browser to make... to give me a new animation frame".
So it takes only one single parameter that is the function you want to call.
Like that, I call the animate function once, I clear, I draw, I move, and instead of calling setTimeout,
I've got to call the same function again.
It's exactly the same principle as setTimeout, except that... you can see: it moves much faster, smoother, it's much more optimized.
The text of the course will describe in detail all the advantages.
In order to do smooth animation, you should use requestAnimationFrame.
And as you can see, there is no second parameter.
The interval of time between each call, the delay before calling again the animate function is 16.6 milliseconds, that corresponds to a 60 frames/second animation.
And that is the target for today's game consoles, for example; when you've got a game at 60 frames per second, it's really a smooth game.
Is it worth completely forgetting about setInterval and setTimeout? The answer is no.
It can be useful for making simple... steps in the animation like changing the color every second or changing the color of this rectangle twice per second.
I will write a function changeColor that will change the color of the rectangle.
So, how can we change the color of the rectangle? We will use the fillStyle property.
Instead of using a hard coded value like this one - red for example - I can use setInterval to call this function at a regular interval of time.
If you do this, you will see that.
Aha sorry, it's not animate it's changeColor... if I do this, you will see that the rectangle starts black... okay, after one second, starts black and turns red.
I can use small tricks like using an array red, blue, green...like that. And I will use an index for the color, I will start with red.
And here, instead of doing that we can use colors...currentColor modulo 3... like this, it will go through different values...and I will increment the color.
Like this, normally, yes... okay...
I've got a rectangle that is just changing colors.
I can also make it bounce.
Move the shapes... if rectangleX > to let's say... 200 pixels for example... I will use a variable called speed... like this normally... okay, I made a mistake somewhere... okay...it bounces so each time the rectangle is superior...at 200 pixels it will change its direction because the increment that was equal to 1 here earlier, is now 1 or -1.
And I can add another test like this.
In that case when the rectangle touches the left side it will bounce again.
If I wanted it to bounce correctly I have to add the width to the test.
The width of the rectangle was 200...100... 80! Okay.
So if I do this, now I've got the rectangle that is bouncing on the screen.
If I wanted it to move faster, I can just, instead of using 1, use a bigger increment.
You saw all the basics, so you can see that we can use requestAnimationFrame for the 60 frames per second animation, and we can use setInterval just to change some states of the shapes like the color, the width, speed or anything.
I can also increment the speed each time it bounces.
Like that.
It will go faster and faster, normally... yes...
It's going faster every time it bounces, no... every time it changes the color it goes faster.
Okay, this is the end of this video, you saw the basic steps.
In another video I will show you how to interact with the animation with the keyboard and with the mouse, and in a third video I will show you how to build an animated monster.
Thanks for watching.
Below is the example shown in the video, with source code:
Errata: in the video, we use speed +=1; in order to increment the speed of the rectangle each time it bounces (in the changeColor() function). This is not correct as speed can be negative. The online example fixes this by using speed += Math.sign(speed) * 1; instead. This will add +1 or -1 depending on the sign of speed.