HTML5 Canvas — étape par étape

Chaque exemple se construit progressivement : on démarre avec très peu de code (Étape 1), puis on ajoute quelques lignes à chaque étape (repérées par ✦ nouveau) jusqu'au résultat final.

Comment lire le cours ? Suis les étapes dans l'ordre. Chaque étape est un exemple complet, exécutable seul. Modifie le code puis clique ▶ Exécuter (ou Ctrl + Entrée) ; restaure le code.
Déjà disponibles dans le code : canvas, ctx (le contexte), loop(fn) (animation), on(cible, type, fn) (événements), helpers.photo / helpers.sprite.

1 Introduction

La balise <canvas> est une zone de dessin vide. Tout se fait en JavaScript via le contexte 2D (ctx), déjà prêt ici. Construisons un premier dessin, ligne par ligne.

Règle d'or : la taille se fixe avec les attributs width/height du canvas, jamais en CSS (sinon le dessin est déformé).
Étape 1 Un rectangle plein

On choisit une couleur, on dessine un rectangle : fillRect(x, y, largeur, hauteur). 2 lignes suffisent.

Étape 2 Une 2ᵉ forme

On change la couleur et on ajoute un second rectangle plus bas.

Étape 3 On ajoute du texte

Dernière touche : une police, une couleur, et fillText(texte, x, y).

2 Le repère (coordonnées)

Origine (0,0) en haut à gauche, x vers la droite, y vers le bas. Visualisons-le en construisant une grille.

Étape 1 Un point

On place juste un point rouge en (120, 80) avec un petit cercle.

Étape 2 Les lignes verticales

On trace une ligne verticale tous les 20 px avec une boucle.

Étape 3 Grille complète + étiquette

On ajoute les lignes horizontales et on écrit les coordonnées du point.

3 Rectangles

Trois fonctions directes. On les découvre une par une.

Étape 1 fillRect — plein
Étape 2 strokeRect — contour
Étape 3 clearRect — efface

On perce un trou transparent dans le rectangle vert.

4 Chemins & lignes

Le crayon : beginPathmoveTolineTostroke/fill. On part d'une ligne et on arrive à un triangle plein.

Étape 1 Une ligne

On pose le crayon (moveTo), on trace jusqu'à un point (lineTo), on encre (stroke).

Étape 2 Plusieurs segments

Plusieurs lineTo à la suite forment une ligne brisée (ici 2 côtés d'un triangle).

Étape 3 Fermer & remplir

closePath relie le dernier point au premier, et fill remplit.

Toujours appeler beginPath() avant une nouvelle forme, sinon les anciens tracés se ré-encrent.

5 Styles de ligne

Étape 1 Épaisseur

Une grosse ligne avec lineWidth.

Étape 2 Les bouts (lineCap)

On compare les 3 types d'extrémités sur 3 lignes.

Étape 3 Pointillés

setLineDash([trait, espace]). On le remet à [] pour revenir au trait plein.

6 Cercles & arcs

arc(x, y, rayon, début, fin) en radians (Math.PI = 180°). On part du cercle complet, puis on n'en garde qu'une portion.

Étape 1 Cercle complet

De l'angle 0 à 2 × Math.PI = tour complet.

Étape 2 Une portion (camembert)

On limite l'arc (0 → 120°) et on relie au centre pour une « part de tarte ».

Étape 3 Pac-Man

Même principe, mais on laisse un « coin » ouvert pour la bouche.

7 Courbes (Bézier)

Le point de contrôle « attire » la courbe. On part d'une ligne droite pour bien voir la différence.

Étape 1 Une droite (référence)
Étape 2 On courbe

quadraticCurveTo(cpx, cpy, x, y) : le 1ᵉʳ couple est le point de contrôle.

Étape 3 Montrer le point de contrôle

On affiche en pointillés les tangentes et le point de contrôle (en rouge) pour comprendre.

8 Couleurs & transparence

Étape 1 Un cercle opaque
Étape 2 Transparence (globalAlpha)

On baisse l'opacité : les cercles se mélangent là où ils se superposent.

Étape 3 Teintes avec hsl()

On ajoute une bande de couleurs en faisant varier la teinte (0–360°).

9 Dégradés

Étape 1 Dégradé linéaire à 2 couleurs

On crée le dégradé, on ajoute 2 étapes de couleur, on l'utilise comme fillStyle.

Étape 2 Une étape intermédiaire

On ajoute une couleur au milieu (position 0.5).

Étape 3 Dégradé radial (boule 3D)

createRadialGradient part d'un petit cercle clair vers un grand cercle foncé.

10 Motifs (patterns)

Étape 1 Fabriquer une tuile

On dessine un petit motif 20×20 dans un canvas séparé, puis on l'affiche une fois pour vérifier.

Étape 2 Répéter la tuile

createPattern(tuile, 'repeat') la répète comme un papier peint.

11 Ombres

Étape 1 Sans ombre
Étape 2 Couleur + flou
Étape 3 Décalage + désactivation

On décale l'ombre, puis on la coupe (shadowColor = 'transparent') pour le texte.

12 Texte

Étape 1 Écrire
Étape 2 Centrer (textAlign)

Avec textAlign='center', le x devient le milieu du texte.

Étape 3 Mesurer (measureText)

On encadre le texte pile à sa largeur grâce à measureText(t).width.

13 Images & sprites

On utilise helpers.photo (image de test 320×200). En vrai : const img = new Image(); img.src='...'; img.onload = () => ctx.drawImage(img,0,0);

Étape 1 Afficher
Étape 2 Redimensionner

4 arguments = position + nouvelle taille.

Étape 3 Découper (sprite)

8 arguments : on prélève un morceau de la source (le soleil) et on l'agrandit.

14 Transformations

On déplace/tourne le repère. save()/restore() permettent d'annuler une transformation.

Étape 1 Un rectangle normal
Étape 2 Déplacer + tourner

On met l'origine au centre (translate), on pivote (rotate), puis on dessine à partir de (0,0).

Étape 3 Un éventail (boucle + save/restore)

On répète 12 fois en tournant un peu plus à chaque tour. save/restore évitent que les rotations s'accumulent.

15 Composition

Étape 1 Mode normal

Par défaut (source-over), le 2ᵉ cercle recouvre le 1ᵉʳ.

Étape 2 Mode multiply

Une seule ligne change tout : les couleurs se multiplient dans la zone commune.

16 Pixels & filtres

Chaque pixel = 4 valeurs dans data : Rouge, Vert, Bleu, Alpha (0–255).

Étape 1 Lire & réafficher

On dessine la photo, on lit les pixels, on les réaffiche tels quels (rien ne change… encore).

Étape 2 Niveaux de gris

On parcourt les pixels (pas de 4) et on remplace R, V, B par leur moyenne.

Étape 3 Négatif

Autre formule : 255 − valeur inverse les couleurs.

17 Animation

Animer = redessiner ~60 fois/seconde. Ici le helper loop(fn) appelle ta fonction à chaque image. Construisons une balle qui rebondit.

Étape 1 Une balle immobile
Étape 2 La faire avancer

Dans loop : on efface, on incrémente x, on redessine. Elle file vers la droite et sort.

Étape 3 Rebondir sur les bords

On ajoute une vitesse verticale et on inverse la vitesse quand on touche un bord.

18 Interactivité (souris)

On convertit la position de la souris en coordonnées du canvas avec getBoundingClientRect().

Étape 1 Réagir au clic

Au clic, on calcule la position et on dessine un point dessus.

clique →
Étape 2 Suivre le mouvement

Même chose mais sur mousemove : une traînée de couleur suit le curseur.

survole →

19 Détourage (clip)

Un chemin peut servir de masque : après clip(), tout ce qu'on dessine n'apparaît qu'à l'intérieur de cette zone.

Étape 1 La zone de découpe

On visualise d'abord le contour qui servira de masque.

Étape 2 Découper une image

On appelle clip() sur le cercle, puis on dessine la photo : elle est rognée en rond.

Étape 3 Projecteur animé

On assombrit la photo, puis on redessine net uniquement dans un cercle qui se déplace : un effet « lampe torche ».

20 Coins arrondis (roundRect)

roundRect(x, y, l, h, rayon) trace un rectangle à coins arrondis. Le rayon peut être un nombre, ou un tableau [hg, hd, bd, bg] pour des coins différents.

Étape 1 Rectangle normal
Étape 2 On arrondit

roundRect définit un chemin → on le remplit ensuite.

Étape 3 Une « carte » d'interface

Coins arrondis + ombre + bandeau (avec coins arrondis seulement en haut) = composant d'UI moderne.

21 Polygones & étoiles (trigonométrie)

Avec cos/sin on place des points sur un cercle. En reliant N points régulièrement espacés, on obtient n'importe quel polygone.

Étape 1 Un polygone (fonction)

L'angle de chaque sommet = i × 2π / nombreDeCôtés.

Étape 2 Plusieurs formes

On change juste le nombre de côtés : 3, 5, 6, 8…

Étape 3 Une étoile

On alterne entre un rayon externe et un rayon interne à chaque sommet.

22 Clic sur formes (isPointInPath)

Le canvas ne mémorise pas les formes, mais isPointInPath(x, y) teste si un point est dans le dernier chemin tracé. Parfait pour rendre des formes cliquables.

Étape 1 Tester un point

On retrace le chemin du cercle puis on demande si le point (160,100) est dedans.

Étape 2 Cercles cliquables

Au clic, on retrace chaque cercle et on teste s'il contient la souris pour l'allumer/éteindre.

clique →

23 Animation de sprite

Une « feuille de sprites » regroupe plusieurs images. En affichant une case différente à chaque instant, on crée une animation. helpers.sprite contient 4 images de 48×48.

Étape 1 Une image

On découpe la 1ʳᵉ case (x de 0 à 48) avec drawImage à 8 arguments.

Étape 2 Faire défiler les cases

On calcule l'index de case à partir du temps : Math.floor(t/150) % 4.

Étape 3 Le faire marcher

On anime les cases ET on déplace le personnage qui traverse l'écran.

24 Filtres (ctx.filter)

La propriété ctx.filter applique des filtres CSS au dessin qui suit : blur(), brightness(), contrast(), grayscale(), sepia(), hue-rotate()… On la remet à 'none' ensuite.

Étape 1 Un flou
Étape 2 Enchaîner des filtres

On combine plusieurs filtres séparés par des espaces.

Étape 3 Réglage à la souris

X de la souris → intensité du flou, Y → luminosité. Un mini studio photo.

survole →

25 Mouvement fluide (easing)

Un mouvement « naturel » accélère puis ralentit. L'astuce la plus simple : à chaque image, se rapprocher de la cible d'un pourcentage de la distance restante.

Étape 1 Vitesse constante (linéaire)

Le carré avance toujours à la même vitesse vers le point cliqué : un peu robotique.

clique →
Étape 2 Avec easing

Une seule ligne change : on avance d'une fraction de la distance → départ rapide, arrivée douce.

clique →

A Cas concret : horloge analogique

On combine arcs, transformations et animation. On construit le cadran, puis les aiguilles une à une, puis on les anime à l'heure réelle.

Étape 1 Le cadran
Étape 2 Les 12 marques

On tourne le repère de 30° à chaque heure pour placer un petit trait.

Étape 3 Une aiguille (fonction)

On crée une fonction réutilisable qui dessine une aiguille selon un angle.

Étape 4 Animer à l'heure réelle

On lit l'heure avec new Date() et on redessine tout dans loop.

B Cas concret : graphique en barres

Visualiser des données. On pose les axes, puis une barre, puis toutes les barres à l'échelle, puis les étiquettes.

Étape 1 Les axes
Étape 2 Une barre

Une barre se dessine de bas en haut (donc y = base − hauteur).

Étape 3 Toutes les barres à l'échelle

On boucle sur les données et on met chaque barre à l'échelle de la valeur max.

Étape 4 Valeurs + étiquettes

C Cas concret : bloc de dessin

Un mini-Paint. On ajoute le comportement pièce par pièce.

Étape 1 Un point au clic
clique →
Étape 2 Tracer en glissant

On garde un drapeau dessine : vrai entre le clic et le relâchement.

clic + glisser →
Étape 3 Trait lisse

Des bouts/angles arrondis (round) rendent le trait fluide.

dessine →

D Cas concret : système de particules

On passe d'une particule à des centaines.

Étape 1 Une particule
Étape 2 Tout un tableau

On crée 80 particules avec des vitesses aléatoires et on les anime toutes.

Étape 3 Gravité, vie & traînée

On ajoute la gravité, une durée de vie (recyclage), et un effacement semi-transparent pour la traînée.

E Cas concret : jauge animée

Étape 1 L'arc de fond

Un arc épais ouvert en bas (de 135° à 405°).

Étape 2 La partie remplie

On dessine par-dessus un arc qui ne couvre qu'une fraction (ici 72 %).

Étape 3 Animer + couleur + texte

La valeur monte doucement vers la cible, la couleur va du rouge au vert, et on affiche le pourcentage.

F Cas concret : mini-jeu Casse-briques

Le projet de synthèse, monté en 4 étapes. Chacune est jouable. Utilise ← → ou la souris.

Étape 1 Décor : raquette + balle

On dessine juste les éléments, immobiles.

Étape 2 La balle bouge & rebondit

On l'anime et on la fait rebondir sur les 3 murs + la raquette.

Étape 3 Contrôler la raquette

On écoute le clavier (et la souris) pour déplacer la raquette.

← →
Étape 4 Briques, score & fin de partie

On ajoute la grille de briques, la détection de collision, le score et l'écran gagné/perdu.

← → ou souris

G Projet : pluie de Matrix

Des colonnes de caractères qui tombent. On part d'un seul caractère, puis on remplit l'écran.

Étape 1 Un caractère qui tombe
Étape 2 Plein de colonnes

Un tableau garde la position Y de chaque colonne. L'effacement semi-transparent crée la traînée.

Étape 3 Tête lumineuse

On dessine le caractère de tête en blanc pour l'effet « goutte brillante ».

H Projet : système solaire

L'exemple roi des transformations imbriquées : une planète tourne autour du soleil, et une lune tourne autour de la planète grâce à un rotate dans un rotate.

Étape 1 Soleil + 1 planète

On place l'origine au centre, on tourne, on s'éloigne (translate), on dessine la planète.

Étape 2 Plusieurs planètes

Un tableau de planètes (distance, taille, couleur, vitesse) + les orbites en gris.

Étape 3 Une lune (rotation imbriquée)

Pendant qu'on est dans le repère de la 2ᵉ planète, on tourne encore pour y attacher une lune.

I Projet : feu d'artifice

On réutilise les particules, mais déclenchées au clic et soumises à la gravité.

Étape 1 Une explosion

40 particules partent dans toutes les directions depuis le centre.

Étape 2 Au clic

On déclenche une explosion là où on clique.

clique →
Étape 3 Fusées automatiques

Des fusées montent du bas et explosent à leur sommet — plus le clic qui marche toujours.

clique aussi →

J Projet : bac à billes (collisions)

De vraies collisions entre billes : détection par distance, séparation, puis échange des vitesses le long de la normale (physique élastique, masses égales).

Étape 1 Des billes rebondissent sur les murs
Étape 2 Elles se cognent entre elles

Pour chaque paire : si la distance < somme des rayons, on les sépare et on échange la composante de vitesse le long de la normale.

K Projet : spirographe

De l'art mathématique : des équations paramétriques (cos/sin combinés) tracent des courbes hypnotiques.

Étape 1 Une rosace

Le rayon varie selon l'angle : r = 80·cos(5·a) donne une fleur à 5 pétales.

Étape 2 Tracé animé (hypotrochoïde)

On ne nettoie jamais le canvas : la courbe se dessine progressivement, couleur changeante.

L Projet : jeu Snake

Le classique, monté en 3 étapes. La logique tourne sur une grille de cases, à un rythme plus lent que l'affichage.

Étape 1 Plateau, serpent & pomme

On dessine la grille en cases, le serpent (vert) et la pomme (rouge), immobiles.

Étape 2 Il bouge & mange

Toutes les 140 ms, on ajoute une tête dans la direction courante ; on retire la queue, sauf si on mange (le serpent grandit). Flèches pour diriger.

flèches ↑↓←→
Étape 3 Murs, collision & game over

Plus de traversée : toucher un mur ou se mordre = perdu. On affiche l'écran de fin.

flèches ↑↓←→

📋 Mémo des méthodes principales

CatégorieMéthodes / propriétés
Contextecanvas.getContext('2d')
RectanglesfillRect, strokeRect, clearRect
CheminsbeginPath, moveTo, lineTo, closePath, fill, stroke
Courbesarc, arcTo, quadraticCurveTo, bezierCurveTo
StylesfillStyle, strokeStyle, lineWidth, lineCap, lineJoin, setLineDash, globalAlpha
Dégradés/motifscreateLinearGradient, createRadialGradient, addColorStop, createPattern
OmbresshadowColor, shadowBlur, shadowOffsetX/Y
TextefillText, strokeText, font, textAlign, textBaseline, measureText
ImagesdrawImage (3 formes)
Transformationstranslate, rotate, scale, save, restore, setTransform
CompositionglobalCompositeOperation
Détourageclip, roundRect, isPointInPath
Filtresctx.filter (blur, brightness, sepia, grayscale, hue-rotate…)
PixelsgetImageData, putImageData, createImageData
AnimationrequestAnimationFrame, cancelAnimationFrame