After this lesson you will be able to:
canvas
Nous avons apris à dessiner programmatiquement dans une zone <canvas>
. C'est plus compliqué que d'utiliser Photoshop. Mais par contre, l'avantage est que l'on va pouvoir animer notre dessin.
Since we're using JavaScript to control <canvas>
elements, it's also very easy to make (interactive) animations. In this lesson, we will take a look at how to do some basic animations.
Probably the biggest limitation is, that once a shape gets drawn, it stays that way. If we need to move it we have to redraw it and everything that was drawn before it. It takes a lot of time to redraw complex frames and the performance depends highly on the speed of the computer it's running on.
When doing animations on canvas
, we have a set of frames that the canvas will render sequentially to create the ilusion of an animation. Each of these steps are represented in canvas by the concept of States.
Pour dessiner une balle qui bouge nous allons donc devoir dessiner chacune des frames d'animation :
In order to draw new frames, we have 4 mandatory steps we need to take:
clearRect()
method.Save and Restore Canvas State?
Canvas states are stored on a stack. Every time the save()
method is called, the current drawing state is pushed onto the stack. A drawing state consists of:
strokeStyle
, fillStyle
, globalAlpha
, lineWidth
, lineCap
, lineJoin
, miterLimit
, lineDashOffset
, shadowOffsetX
, shadowOffsetY
, shadowBlur
, shadowColor
, globalCompositeOperation
, font
, textAlign
, textBaseline
, direction
, imageSmoothingEnabled
.You can call the save()
method as many times as you like. Each time the restore()
method is called, the last saved state is popped off the stack and all saved settings are restored.
Shapes are drawn to the canvas
by using the canvas
methods directly or by calling custom functions
. In normal circumstances, we only see these results appear on the canvas
when the script finishes executing.
For instance, it isn't possible to do an animation from within a for
loop.
That means we need a way to execute our drawing functions
over a period of time.
Par ex :
Pour animer notre rond, nous allons :
x
drawFrame()
Nous allons donc pouvoir utiliser setInterval
:
Ou bien nous pourrions aussi utiliser setTimeout()
First there's the window.setInterval()
, window.setTimeout()
, and window.requestAnimationFrame()
functions, which can be used to call a specific function over a set period of time.
setInterval(method, delay)
// Starts repeatedly executing the function specified by method every delay milliseconds.
setTimeout(method, delay)
// Executes the function specified by function in delay milliseconds.
requestAnimationFrame()
Le problème avec setInterval
et setTimeout
c'est qu'elles ne vont pas être optimisées pour de l'animation. Notre animation risque de lagguer !
On va donc plutôt utiliser requestAnimationFrame
:
requestAnimationFrame(callback)
// Tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint.
The window.requestAnimationFrame()
method tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint. The method takes as an argument a callback
to be invoked before the repaint.
requestAnimationFrame
va demander au navigateur, quand il aura du temps, d'éxécuter anim
.
You should call this method whenever you're ready to update your animation onscreen. This will request that your animation function
be called before the browser performs the next repaint. The number of callbacks
is usually 60 times per second, but will generally match the display refresh rate in most web browsers as per W3C recommendation.
Your callback
routine must itself call requestAnimationFrame()
if you want to animate another frame at the next repaint.
Let´s see an example to better understand how can we update our canvas
element. In the following example, we will change the color of the square we draw.
It may seem that we are just changing the fillColor
but actually, we are redrawing everything. First, we clear the canvas
using the clearRect()
method, and the draw again our square giving a random color to the fillRect()
method.
Now we know how to update our canvas
, let´s try to move an element inside it. For moving an element we will add(or subtract, depending the direction we want to move our element) a certain quantity depending on the speed we want to set to the elements.
On the following example, we will move 3 elements, each of them in with a specific "speed". Let´s do it step by step:
canvas
element and set the context. Then we will create three red squares, located in different coordinates of our canvas
. Also, we are going to create three variables to control the speeds of our elements.updateCanvas()
function.updateCanvas()
function, where we increment the speed of our elements in three differents quantities, this way we will get various speeds. Don´t forget we need to call out window.requestAnimationFrame(updateCanvas)
method, so our canvas
updates.Go ahead and make the elements move in the opposite direction, that means, from bottom to the top of the canvas. You can choose the speed! 🏎️
🏋🏾♂️
Créer une animation d'un rectangle 50x30 allant du bord droit d'un canvas de 400x300 au bord gauche.
Updating the canvas
, moving elements… we are becoming experts on this!
To develop our games we will need some user interaction. We will now learn how can we make our elements follow user's actions.
We will move one of the Pacman´s enemies in the following example. Notice that in this example, we call the update
function every time somebody presses a key in the keyboard.
Let´s do it step by step:
canvas
and set the 2d context. We will add some captions to know the exact coordinates our ghost is located, that way we also declare fillStyle
and font
properties.x
and y
properties in order to place it on the canvas
. Besides, we will add some functions to move it according to the user interaction with the keyboard. Each function will add or subtract from x
or y
axis.L6, expliquer le chargement de l'image.
updateCanvas()
function, where we clear our canvas
and redraw the element.Notice that we are displaying our Ghost position x
and y
so we can check how it updates with every arrow key clicked!
In the following CodePen you have all the code we just explain, go ahead and take a look of our ghost moving!
We may want to restart everything, putting the ghost on it initial position. Let´s do it using the spacebar
key.
Go ahead and add the functionality in the codePen. When somebody clicks on the spacebar
our ghost should return to the position (50,50)
.
When rendering a 2d game, usually we need a background image that moves while our character or element is moving through the canvas
.
Think about a game like SuperMario Bros and notice there was an infinite background like the following:
Using canvas
we can use a panoramic image and loop infinitely over it to be able to show the whole image. Check the codePen and see how we can do this using canvas
and image
.
Expliquer le trick d'afficher 2 images.
Now canvas
get a lot more interesting for our game project huh? We just learn how to animate elements, schedule the animations and make them interactive with users.
Best way to turn an expert on animations is practice, so feel free to keep playing with codePens or create ones by yourself!