Canvas

Tandis qu’il est possible d’utiliser CSS et JavaScript pour animer les images vectorielles SVG - puisqu’elles sont définies par le balisage - cette manière n’est pas efficace pour créer des animations de jeux, des scènes 3D, et autres animations graphiques généralement traitées par les langages de bas niveau tels que C++ ou Java.

<canvas> et l’API Canvas permet de créer des images bitmap scriptées. Ce n’est pas très utile pour créer des images statiques mais plutôt pour créer des images dynamiquement, comme des animations 2D et visualisations de données en temps réel.

Exemple animation Canvas 2D

Il existe également une implémentation de canvas 3D, WebGL, une API qui permet de créer de véritables graphiques 3D dans le navigateur web. Nous ne l’aborderons pas dans cet article


Créer un canvas

Pour créer une scène 2D ou 3D sur une page, il faut nécessairement avoir un élément <canvas>. Du contenu alternatif peut être mis à l’intérieur, il ne sera affiché que si le navigateur ne prend pas en charge les canvas.

<canvas width="320" height="240">
  <p>Votre navigateur ne prend pas en charge canvas!</p>
</canvas>

Les attributs width et height sont facultatifs. Les dimensions par défaut sont de 300 pixels par 150. On peut également les mettre à jour via JavaScript.

var canvas = document.querySelector('canvas'),
    width  = canvas.width = window.innerWidth,
    height = canvas.height = window.innerHeight;

Notez que si vous définissez les dimensions du canvas aux dimensions de la fenêtre, il est nécessaire de supprimer les margin du <body> pour ne pas avoir de scrollbar.

body {
  margin: 0;
  overflow: hidden;
}

Par défaut, le canvas n’affiche rien du tout, il faut utiliser JavaScript pour afficher du contenu à l’écran.

La taille du canvas doit être spécifié soit via les attributs HTML soit via JavaScript. En utilisant CSS pour dimensionner le canvas, le dimensionnement du canvas est effectué après que le contenu du canvas n’ait été calculé, et comme toute autre image, elle peut devenir pixelisée/déformée (puisque le canvas une fois affiché n’est plus qu’une simple image).


Récupérer le contexte

Pour dessiner sur le canvas, la première chose à faire est de récupérer une référence à la zone de dessin, appelé le contexte du canvas.

if(!canvas.getContext) {
    return;
}
var ctx = canvas.getContext('2d');

Toutes les opérations de dessin impliqueront d’utiliser cet objet.
Au début le canvas est complètement vide, il ne s’agit que d’un rectangle transparent.


Dessiner des formes

À l’intérieur de ce contexte, on peut ajouter différentes formes, comme des rectangles, lignes, cercles, etc.
Les éléments sont dessinés dans l’ordre dans lequel ils apparaissent dans le code: les premiers se trouvent en dessous des derniers. Lorsque qu’une forme est dessinée, il est impossible de la modifier - ce ne sont plus que des pixels sur une image bitmap.

Les éléments sont dessinés par rapport à l’origine du canvas, qui est par défaut le point supérieur gauche du canvas (0,0).
La valeur de x déplace la forme vers la droite, et la valeur de y vers le bas.

Il n’existe pas de méthode à proprement parler pour changer la couleur de fond du canvas. Pour ce faire, on ajoute un rectangle qui recouvre toute la surface du canvas.

Exemple:

var canvas = document.getElementById('canvas'),
    ctx    = canvas.getContext('2d');

// Définit la taille du canvas
canvas.width  = 100;
canvas.height = 100;

// Ajoute un rectangle noir pour créer le fond
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, 100, 100);

// Dessine deux rectangles
ctx.fillStyle = 'white';
ctx.fillRect(5, 5, 50, 50);

ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 50, 50);

JSFiddle

Différentes propriétés peuvent être définies sur le contexte pour customiser la mise en forme: couleur du fond, couleur de la bordure, épaisseur du trait, etc. Une fois que les propriétés sont définies, on peut appeler les méthodes du contexte pour tracer la forme.

Pour créer une forme avec des bords arrondis, il n’existe pas de propriété border-radius, il est nécessaire de “tricher”: on définit la propriété lineJoin = "round" et on crée une bordure de la même couleur que le fond. JsFiddle border-radius.


Rectangle

Comme pour tout élément du canvas, il faut au préalable définir les propriétés du contexte (couleur, épaisser du trait…) avant de tracer la forme.

ctx.lineWidth = 5;                      // définit l'épaisseur du contour
ctx.fillStyle = 'rgb(0, 255, 0)';       // définit la couleur du contour
ctx.strokeStyle = 'rgb(255, 255, 255)'; // définit la couleur du fond

Lignes

On peut dessiner des lignes droites et/ou courbes.
Pour ce faire, on a plusieurs méthodes qui permettent de spécifier où déplacer le stylo sur le canvas.

Les méthodes utiles pour tracer des lignes droites:

Méthode Description
beginPath() Commence un nouveau chemin au point où se situe le stylo sur le canvas. Sur un nouveau canvas, le stylo commence au point (0, 0).
moveTo() Déplace le stylo à un point différent sur le canvas, sans tracer de ligne - le stylo “saute” simplement vers une nouvelle position.
lineTo() Ajoute une ligne droite qui part de la position actuelle du stylo et va aux coordonnées spécifiées - le stylo est déplacé vers cette nouvelle position.
closePath() Ajoute une ligne droite qui part de la position actuelle du stylo et va au point de départ du chemin en cours.

Une fois que le chemin est spécifié, alors on peut alors tracer le trait avec stroke() et/ou remplir la forme avec fill().

Exemple:

var canvas = document.getElementById('canvas'),
    ctx    = canvas.getContext('2d');

// Définit la taille du canvas
canvas.width  = 100;
canvas.height = 100;

// Ajoute un fond
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, 100, 100);

// Dessine une triangle
ctx.beginPath();     // ouvre un nouveau chemin
ctx.moveTo(10,10);   // définit le point de départ du chemin
ctx.lineTo(100,10);  // ajoute la 1ère ligne droite
ctx.lineTo(60,60);   // ajoute la 2ème ligne droite
ctx.closePath();     // ferme le triangle (ajoute la 3ème ligne droite)

ctx.fillStyle = "lightblue";
ctx.fill();          // remplit la forme

Courbes quadratiques et courbes de Bézier

Pour dessiner des lignes courbes, plutôt que lineTo(), on a le choix entre deux méthodes: quadraticCurveTo(), pour des courbes de Bézier cubiques, ou bezierCurveTo(), pour ces courbes de Bézier quadratiques.

Exemple:

ctx.beginPath();
ctx.strokeStyle = "white";
ctx.lineWidth = 3;

var left   = 5,
    top    = 10,
    right  = left + 50,
    bottom = top + 80;

ctx.moveTo(left, top);
// Origine: (left, top)

ctx.bezierCurveTo(right, top, left, bottom, right, bottom);
// Point de controle 1 : courbe (right, top)
// Point de controle 2 : courbe (left, bottom)
// Destination : (right, bottom)

ctx.stroke();
ctx.closePath();

Cercles et arcs de cercle

Pour tracer des cercles ou des arcs de cercle, on utilise la méthode arc(). Cette méthode prend 6 paramètres:

arc(x, y, rayon, angle_debut, angle_fin, sens_antihoraire)
Paramètres Description
x, y Position du centre du cercle
rayon Rayon du cercle
angle_debut, angle_fin Angles de début et de fin, en radians, pour dessiner l’arc (donc des angles de 0 et 360 degrés donnent un cercle fermé)
sens_antihoraire Définit si le cercle doit être dessiné dans le sens des aiguilles d’une montre ou dans le sens inverse (false pour le sens horaire)

Exemple:

Dessine un cercle complet, de rayon 40 pixels:

ctx.beginPath();
ctx.arc(50, 50, 40, degToRad(0), degToRad(360), false);
ctx.fillStyle = "lightblue";
ctx.fill();

Dessine un Pacman, de rayon 50 pixels, aux coordonnées (200,106):

ctx.beginPath();
ctx.arc(50, 50, 40, degToRad(-45), degToRad(45), true);
ctx.lineTo(50, 50);
ctx.fillStyle = 'yellow';
ctx.fill();

Fonction degToRad:

La fonction degToRead est utilisée pour convertir une valeur en degrés vers une valeur en radians. Chaque fois que devez fournir une valeur d’angle en JavaScript, ce sera presque toujours en radians - mais les humains pensent généralement en degrés.

function degToRad(degrees) {
  return degrees * Math.PI / 180;
}

Texte

Il existe deux méthodes pour dessiner du texte: fillText() pour dessiner un texte rempli, strokeText() pour dessiner un contour de texte. Toutes deux prennent trois paramètres:

fillText(text, x, y)

Par défaut, les coordonnées (x,y) définissent la position du coin inférieur gauche de la zone de texte. Il est possible de modifier ce comportement grâce aux propriétés textAlign (pour l’alignement horizontal) et textBaseline (pour l’alignement vertical). La police et la taille du texte peuvent être définies avec la propriété font (même format que la propriété CSS font).

Exemple:

Dessiner le contour du texte:

ctx.strokeStyle = 'white';
ctx.lineWidth = 1;
ctx.font = '36px arial';
ctx.strokeText('Canvas text', 50, 50);
Text

Dessiner un texte rempli:

ctx.fillStyle = 'white';
ctx.font = '36px georgia';
ctx.fillText('Text', 10, 36);
Text

Modifier l’alignement du texte:

ctx.fillStyle = 'white';
ctx.font = '36px sans';
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.fillText('Text', 50, 10);
Text

Image

Il est possible d’inclure une image externe dans un canvas. Pour ce faire, on doit au préalable récupérer un élément HTMLImageElement: soit on sélectionne une image présente dans la page (balise img), soit on la charge dynamiquement avec le constructeur Image().

var image = new Image();
image.src = 'firefox.png';

Une fois l’image chargée, elle peut être ajoutée au canvas avec drawImage().
Cette méthode peut prendre 3 arguments ou 9.

Version courte

Il faut donner au minimum trois paramètres: l’image et les coordonnées (x,y) du coin supérieur gauche de l’image.

drawImage(resource, x, y)
image.onload = function() {
  ctx.drawImage(image, 50, 50);
}

Version complète

La version complète permet en plus de tronquer et redimensionner l’image. Elle prend 9 paramètres:

drawImage(resource, sx, sy, sWidth, sHeight, x, y, width, height)
Paramètres Description
resource L’élément HTMLImageElement
sx, sy Les coordonnées à partir d’où découper l’image, relativement au coin supérieur gauche de l’image d’origine. Tout ce qui est à gauche de sx ou au-dessus de sy ne sera pas dessiné.
sWidth, sHeight La largeur et la hauteur de l’image que l’on veut découper, à partir du coin supérieur gauche de la découpe.
x, y Les coordonnées de l’image sur le canvas, relativement au coin supérieur gauche du canvas.
width, height La largeur et hauteur affichée de l’image. En spécifiant des dimensions différentes de sx, sy, l’image est redimensionnée/déformée.

Exemple:

ctx.drawImage(
  image,
  20, 20,      // couper 20 pixels à gauche et 20 pixels en haut
  185, 175,    // dimensions de la découpe
  50, 50,      // position sur le canvas
  185, 175     // dimensions affichée (en l'occurence, identique à l'origine)
);

Path2D

L’objet Path2D permet de garder en mémoire des instructions de dessin, ce qui permet de factoriser le code. Disponible dans les navigateurs récents.

var shape = new Path2D();
shape.rect(10, 10, 50, 50);

Path2D permet également d’utiliser des trajets SVG sur le canvas.

var p = new Path2D("M10 10 h 80 v 80 h -80 Z");

Exemple:

// Définit une forme
var shape = new Path2D();
shape.rect(5, 5, 50, 50);

// Dessine la forme en blanc
ctx.fillStyle = 'white';
ctx.fill(shape);

// Déplace l'origine du canvas et dessine la forme en rouge
ctx.translate(5, 5);
ctx.fillStyle = 'red';
ctx.fill(shape);

Les propriétés du contexte

fillStyle: définir la couleur de fond

La propriété ctx.fillStyle est utilisée pour définir la couleur de fond en cours.
Tous les éléments ajoutés sur le canvas (des rectangles, des cercles, etc) prendrons cette couleur pour couleur de fond.

Les valeurs de couleur acceptées sont les mêmes qu’en CSS (nom de couleur, rgb, rgba…).
Ainsi, il est possible de rendre un canvas semi-transparent en utilisant des couleurs semi-transparentes:

ctx.fillStyle = 'rgba(255, 0, 255, 0.75)';

Il est possible de créer des gradients et d’affecter cet objet aux propriétés fillStyle ou strokeStyle (cf createLinearGradient()).

strokeStyle: définir la couleur du trait

Outre la couleur de fond, on peut définir la couleur de trait en cours avec ctx.strokeStyle.
Même principe que fillStyle sauf que strokeStyle définit la couleur du contour de l’élément et non de la couleur de remplissage.

ctx.strokeStyle = 'rgb(255, 255, 255)';

lineWidth: définir l’épaisser du trait

Par défaut, l’épaisseur de trait est de 1 pixel. On peut le rendre plus épais en spécifiant le nombre de pixels du trait via la propriété ctx.lineWidth.

ctx.lineWidth = 5;

lineCap: définir l’extrémité des lignes

La propriété lineCap définit comment les extrêmités de chaque ligne sont dessinées.
Il y a trois valeurs possibles:

ctx.lineCap = "round";

lineJoin: définir les jointures entre deux segments

La propriété lineJoin définit comment deux segments (lignes, arcs ou courbes) sont joints ensemble.
lineJoin n’a pas d’effet si les deux segments connectés ont la même direction, parce qu’aucune zone de jointure ne sera ajoutée dans ce cas.
Il existe trois valeurs possibles:

ctx.lineJoin = "round";

Pour les jointures de type miter, il est possible de spécifier la longueur maximale du bord extérieur ajouté avec la propriété miterLimit. Plus l’angle est aigu, plus la distance est elevée. La valeur par défaut est 10. Au-delà de cette valeur, une jointure en biseau (bevel) sera affichée à la place.

JsFidlle miterLimit

setLineDash(), lineDashOffset: dessiner des pointillés

La méthode setLineDash() accepte une liste de nombres qui spécifie les distances pour dessiner alternativement une ligne et un espace. La propriété lineDashOffset définit un décalage pour commencer le motif.

ctx.setLineDash([4, 2]);
ctx.lineDashOffset = 2;

shadow: afficher des ombres

Il existe 4 méthodes pour créer une ombre

Exemple:

ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.shadowBlur = 2;
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';

ctx.font = '36px sans';
ctx.fillStyle = 'black';
ctx.fillText('Text', 10, 36);

globalCompositeOperation: changer le type de composition

Il est possible de spécifier le type d’opération de composition à appliquer lorsqu’on dessine de nouvelles formes. Par défaut, on dessine les formes par-dessus le contenu existant. Il est possible d’effectuer des multiplications, des soustractions, sur le même principe que les layers Gimp.

Documentation MDN


Les méthodes du contexte

fill(): remplir une forme

Remplit le chemin en cours avec le style définit par ctx.fillStyle.

stroke(): tracer un chemin

Remplit le chemin en cours avec le style définit par ctx.strokeStyle et l’épaisseur de trait définit par ctx.lineWidth.

ctx.rect(75, 75, 100, 100);

ctx.lineWidth = 5;
ctx.strokeStyle = 'rgb(255, 0, 0)';
ctx.stroke();

clip(): créer un détourage

On peut utiliser la méthode clip() à la place de closePath(). Cela a pour effet de créer, non pas une forme, mais un détourage: toutes les formes qui seront ajoutées par la suite au canvas seront tronquées, limitées à l’intérieur du détourage.

Exemple:

// Définit un clip: tout ce qui suit est limité à un cercle
ctx.beginPath();
ctx.arc(50,50,40, degToRad(0), degToRad(360), false);
ctx.clip();

// Dessine un rectangle rouge
ctx.fillStyle = "red";
ctx.fillRect(0,0,100,100);

// Dessine un rectangle blanc
ctx.fillStyle = "white";
ctx.fillRect(0,0,50,100);

NB Le détourage fait bien partie de l’état du canvas, il est donc sauvegardé par save().

createLinearGradient(), createRadialGradient(): créer un gradient

Il est possible d’utiliser un gradient comme couleur de remplissage.
Pour ce faire, il faut

  1. créer un nouveau gradient, linéaire ou radial:

    • createLinearGradient(x1, y1, x2, y2) pour créer un dégradé linéaire.
      x1, y1 est le point de départ du gradient, x2, y2 est le point d’arrivée

    • createRadialGradient(x1, y1, r1, x2, y2, r2) pour créer un dégradé radial.
      x1,y1,r1 est le premier cercle - de coordonnées (x1,y1) et rayon r1, x2,y2,r2 est le deuxième cercle

  2. assigner des couleurs avec gradient.addColorStop(position, color).
    Chaque appel à addColorStop ajoute une nouvelle couleur au gradient. On définit la position de la couleur entre 0 (le début du gradient) et 1 (la fin du gradient).

Exemple:

Gradient linéaire:

var gradient = ctx.createLinearGradient(0,0,200,0);
gradient.addColorStop(0, "green");
gradient.addColorStop(1, "white");
ctx.fillStyle = gradient;
ctx.fillRect(10,10,200,100);

Gradient radial:

var gradient = ctx.createRadialGradient(100, 100, 50, 100, 100, 100);
gradient.addColorStop(0, 'white');
gradient.addColorStop(1, 'green');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 200, 200);

Autre gradient radial:

var gradient = ctx.createRadialGradient(45, 45, 30, 52, 50, 50);
gradient.addColorStop(0, '#A7D30C');
gradient.addColorStop(0.9, '#019F62');
gradient.addColorStop(1, 'rgba(1, 159, 98, 0)');

ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 150, 150);

createPattern(): créer un motif

Il est également possible d’utiliser une image comme remplissage.
Pour ce faire, créer un motif avec createPattern(image, repeat).

Exemple:

var img = new Image();
img.src = 'https://gist.githubusercontent.com/a-mt/372caa0b4114d22ac2fca4c52aeaff4e/raw/ccb6b5562bafd61cbf57f8eed5502ae3cea6f32d/index.png';

img.onload = function() {
  var pattern   = ctx.createPattern(img, 'repeat');
  ctx.fillStyle = pattern;
  ctx.fillRect(0, 0, 200, 100);
};

translate(): déplacer l’origine des coordonnées

Par défaut, l’origine des coordonnées se situe au coin supérieur gauche du canvas (0,0).
Il est possible de déplacer l’origine des coordonnées, par exemple pour le mettre au centre du canvas:

ctx.translate(width/2, height/2);

Cette fonction est particulièrement utile lorsqu’on ajoute plusieurs formes identiques, plutôt que de modifier les coordonnées de la forme, on modifie l’origine du repère.

ctx.fillRect(20,20,50,50); // rectangle 1
ctx.translate(30,30);
ctx.fillRect(20,20,50,50); // rectangle 2, en décalage de (30,30) pixels par rapport au premier

rotate(): faire pivoter le canvas

La fonction rotate() permet de faire pivoter le canvas. Elle prend un angle de rotation horaire (en radians) en paramètre. Utiliser des angles négatifs pour un sens anti-horaire.

ctx.rotate(45 * Math.PI / 180);

Le centre de la rotation est l’origine du canvas. Pour changer le centre, il faut déplacer l’origine du canvas.

scale(): mettre à l’échelle le canvas

scale(x,y) permet d’augmenter ou diminuer les unités de la grille du canvas. Les valeurs inférieures à 1.0 réduisent la taille (0.5 = moitié de la taille) et les valeurs supérieures à 1.0 augmentent la taille (2.0 = double de la taille), tandis que la valeur 1.0 laisse le canvas à la même taille.

En utilisant des nombres négatifs, on peut réaliser une mise en miroir d’un axe.

ctx.scale(1, -1);
ctx.font = '48px serif';
ctx.fillText('Hello World', 0, 0);

ctx.scale(-1, 1);
ctx.font = '48px serif';
ctx.fillText('Hello World', -width, 48);

setTransform(), resetTransform(): appliquer une transformation

setTransform() permet d’appliquer une matrice de transformation au canvas.
La matrice de transformation est décrite par

// Matrice par défaut
ctx.fillStyle = "green";
ctx.setTransform(1,0,0,1,0,0);
ctx.fillRect(0,0,100,100);

// Skew
ctx.fillStyle = "red";
ctx.setTransform(1,1,0,1,0,0);
ctx.fillRect(0,0,100,100);

resetTransform() réinitialise la transformation en cours à la matrice identité.
C’est un raccourci pour setTransform(1, 0, 0, 1, 0, 0).

save(), restore(): sauvegarder les configurations

La méthode save() permet de sauvegarder l’état du canvas dans sa globalité. Sont sauvegardés:

La méthode restore() restore la sauvegarde la plus récente du canvas.

clearRect(): effacer une zone du canvas

La méthode ctx.clearRect() permet d’effacer le canvas. Elle prend quatre paramètres:

clearRect(x,y,width,height)
Paramètres Description
x,y Coordonnées du coin supérieur gauche de la zone à effacer
width,height Largeur et hauteur de la zone

Cette méthode va effacer la zone spécifiée (tout, y compris l’arrière-plan). Ou on peut utiliser ctx.fillRect().


ImageData

L’objet ImageData permet de lire et écrire le canvas pour manipuler les pixels un par un. La méthode getImageData(x,y,width,height) permet de récupérer un ImageData et putImageData(imageData,x,y) d’appliquer un ImageData au canvas.

Exemple:

Récupérer la couleur du canvas à un endroit donné:

var pixel = ctx.getImageData(x, y, 1, 1),
    data  = pixel.data,
    rgba  = 'rgba('
              + data[0] + ', '
              + data[1] + ', '
              + data[2] + ', '
              + (data[3] / 255)
            + ')';

Inverser les couleurs du canvas:

var imageData = ctx.getImageData(0, 0, width, height),
    data      = imageData.data;

for (var i = 0; i < data.length; i += 4) {
  data[i]     = 255 - data[i];     // rouge
  data[i + 1] = 255 - data[i + 1]; // vert
  data[i + 2] = 255 - data[i + 2]; // bleu
}
ctx.putImageData(imageData, 0, 0);

Mettre en niveau de gris:

var imageData = ctx.getImageData(0, 0, width, height),
    data      = imageData.data;

for (var i = 0; i < data.length; i += 4) {
  var moy = (data[i] + data[i + 1] + data[i + 2]) / 3;
  data[i]     = moy; // rouge
  data[i + 1] = moy; // vert
  data[i + 2] = moy; // bleu
}
ctx.putImageData(imageData, 0, 0);

Enregistrer le canvas

La méthode toDataURL() du canvas (et non du contexte) prend un type MIME en paramètre (image/png si omis) et retourne l’image dans le format spécifié (URI). Pour une image jpeg, il est possible de préciser la qualité de l’image (entre 0 et 1) en deuxième paramètre.

L’uri retournée peut être utilisée pour créer un élément image dans la page, ou ouvrir l’image dans un nouvel onglet.

var uri = canvas.toDataURL(),
    img = document.createElement('img');
img.src = uri;
document.body.appendChild(img);

JsFiddle toDataURL


Animation

window.requestAnimationFrame(): créer une animation de 60 images par secondes

La fonction window.requestAnimationFrame() prend en paramètre une fonction qui sera exécutée dès que le navigateur est prêt. Si votre fonction de callback met à jour le canvas puis appelle de nouveau window.requestAnimationFrame(), et ce continuellement, le résultat obtenu est une animation fluide et agréable pour l’oeil humain - avec un taux de rafraichissement idéal de 60 images par seconde.

Le navigateur s’occupe des détails complexes tels qu’exécuter l’animation à une vitesse constante, et ne pas gaspiller de ressources en animant des choses qui ne sont pas visibles.

function loop() {
  ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
  ctx.fillRect(0, 0, width, height);

  while(balls.length < 25) {
    var ball = new Ball();
    balls.push(ball);
  }

  for(i = 0; i < balls.length; i++) {
    balls[i].draw();
    balls[i].update();
    balls[i].collisionDetect();
  }

  requestAnimationFrame(loop);
}

loop();

Voir exemple Canvas 2D de balles rebondissantes

Une fois que le canvas est dessiné, il est impossible modifier les formes existantes. Pour modifier le canvas, il nécessaire d’effacer et de redessiner, soit en effaçant tout, soit en effaçant la zone minimale nécessaire (en gardant du code pour).

Pour des scènes complexes, on peut empiler plusieurs canvas positionnés en absolu et utiliser les canvas comme des calques - un canvas pour le fond, un pour le menu, un pour le jeu à proprement parler…

Animations avancées

window.cancelAnimationFrame(): annuler l’appel

La boucle s’arrête lorsque vous vous arrêtez d’appeler window.requestAnimationFrame() ou si vous appelez window.cancelAnimationFrame() avant que votre fonction de callback n’ait été exécutée. C’est une bonne pratique de le faire, pour s’assurer qu’aucune mise à jour n’attend d’être exécutée.


Pour aller plus loin: 31 days of Canvas tutorials