Try   HackMD

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Canvas | Basic Animations

Learning Goals

After this lesson you will be able to:

  • Create animations using canvas
  • Understand different ways to schedule the updates
  • Learn how to move elements on the canvas
  • Understand how to move elements from user interactions
  • Learn how to loop over an image to create awesome backgrounds
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

Introduction

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.

Animations Steps

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 :

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Controlling our Animations

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.

Scheduling updates

Par ex :

var x = 0;

function drawFrame() {
  ctx.clearRect(0,0, 500,500);
  
  x++;
  
  ctx.beginPath();
  ctx.arc(50+x,100, 50, 0,2*Math.PI);
  ctx.fill();
}

Pour animer notre rond, nous allons :

  • incrémenter x
  • appeler drawFrame()

Nous allons donc pouvoir utiliser setInterval:

setInterval(function () {
  x += 1;
  drawFrame();
}, 1000/24)

Ou bien nous pourrions aussi utiliser setTimeout()

function anim() {
  x += 1;
  drawFrame();
  
  setTimeout(anim, 1000/24);
}
anim();

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 :

function anim() {
  x += 1;
  drawFrame();
  
  requestAnimationFrame(anim);
}
requestAnimationFrame(anim);

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.

🏋🏾‍♂️
Créer une animation d'un rectangle 50x30 allant du bord droit d'un canvas de 400x300 au bord gauche.

Controlling the elements with User interaction

Updating the canvas, moving elements we are becoming experts on this!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

To develop our games we will need some user interaction. We will now learn how can we make our elements follow user's actions.


Pacman Project - Intro to AI @ UC Berkeley

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:

  1. Create our 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.
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = 'white'; ctx.font = '18px serif';
  1. Now we are going to create our ghost object. It should have 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.
class Ghost { constructor() { this.x = 25; this.y = 25; // Load the image var img = document.createElement('img'); img.onload = () => { // Once image loaded => draw this.img = img; this.draw(); }; img.src = "https://media.giphy.com/media/Qr8JE9Hvi7ave/200.gif"; } moveUp() { this.y -= 25; } moveDown() { this.y += 25; } moveLeft() { this.x -= 25; } moveRight() { this.x += 25; } draw() { ctx.drawImage(this.img, this.x, this.y, 50, 50); } } var ghost = new Ghost();

L6, expliquer le chargement de l'image.

  1. Ok, our ghost is created, so let´s add the listeners for keys, so we can call our functions to move the ghost.
document.onkeydown = function(e) { switch (e.keyCode) { case 38: ghost.moveUp(); console.log('up', ghost); break; case 40: ghost.moveDown(); console.log('down', ghost); break; case 37: ghost.moveLeft(); console.log('left', ghost); break; case 39: ghost.moveRight(); console.log('right', ghost); break; } updateCanvas(); }
  1. Finally, we will need our 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!

function updateCanvas() { ctx.clearRect(0,0,1500,1700); ctx.fillText("Ghost_x: " + ghost.x, 580,40); ctx.fillText("Ghost_y: " + ghost.y, 580,60); ghost.draw() }

In the following CodePen you have all the code we just explain, go ahead and take a look of our ghost moving!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Your turn

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).

Infinite looping an Image

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.

Summary

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!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Extra Resources