TP 2 · Dessiner en JavaScript

Canvas : dessiner des cercles

La balise <canvas> est une surface de dessin : on y trace des formes pixel par pixel, en JavaScript. Objectif du TP : une cible de cercles concentriques de plus en plus opaques vers le centre.

1. Le canvas et son repère

Le canvas se déclare en HTML avec sa taille en pixels, puis on récupère en JavaScript son contexte 2D : l'objet qui possède tous les outils de dessin (on l'appelle presque toujours ctx).

HTML

<canvas id="monCanvas"
        width="400" height="400">
</canvas>

JavaScript

const canvas = document.getElementById("monCanvas");
const ctx = canvas.getContext("2d");
(0, 0) x y (200, 200) (400, 400)
L'origine est en haut à gauche et l'axe y descend : l'inverse des maths.

2. Tracer un cercle

Dessiner sur un canvas se fait toujours en trois temps :

1. Commencer un tracé

ctx.beginPath() : on repart d'une feuille de calque vide, sans relier au dessin précédent.

2. Décrire la forme

ctx.arc(x, y, rayon, début, fin) : rien n'apparaît encore, on décrit le chemin.

3. Peindre

ctx.stroke() dessine le contour, ctx.fill() remplit l'intérieur.

Les angles de arc sont en radians : un tour complet vaut 2 * Math.PI (environ 6,28). Un cercle entier va donc de 0 à 2 * Math.PI ; s'arrêter à Math.PI donnerait un demi-cercle.

Couleur et épaisseur se règlent sur le contexte, comme on choisit un pinceau avant de peindre : ctx.strokeStyle (couleur du contour), ctx.fillStyle (couleur de remplissage), ctx.lineWidth (épaisseur). Ils restent valables pour tous les tracés suivants, jusqu'à ce qu'on les change.

Ce code n'affiche rien. Pourquoi ?

ctx.beginPath();
ctx.arc(200, 200, 80, 0, 2 * Math.PI);
ctx.strokeStyle = "red";

3. Des cercles concentriques : raisonner avant de coder

On veut 8 cercles de même centre, le plus grand (rayon 180) presque transparent, puis de plus en plus petits et de plus en plus opaques, le dernier étant totalement opaque. Avant d'écrire la boucle, remplissons le tableau des valeurs à la main, avec ecart = 180 / 8 = 22,5 :

i012…7
rayon180157,5135…22,5
opacité1/82/83/8…8/8 = 1

On lit la règle dans le tableau : à chaque tour, le rayon perd un ecart, donc rayon = maxRayon - i * ecart ; l'opacité vaut (i + 1) / nbCercles. Et la boucle va de i = 0 à i = 7 : c'est la forme classique for (let i = 0; i < nbCercles; i++).

Piège : décaler le compteur d'une case

Avec for (let i = 1; i <= nbCercles; i++) et la même formule, le premier rayon vaut 157,5 (le cercle de 180 disparaît) et le dernier vaut 180 - 8 × 22,5 = 0 : un cercle invisible. Le tableau des valeurs, rempli avant de coder, permet de voir ce genre d'erreur tout de suite.

Suivez la boucle pas à pas (ici avec 4 cercles, pour aller plus vite) :

À retenir