Le constructeur Path2D

Bonne nouvelle : la dernière version de l'API Canvas introduit un constructeur d'objets : Path2D().
L'un des gros inconvénient de l'API Canvas dans sa version initiale est qu'il fallait redessiner les formes à chaque fois.
Grâce à ce constructeur il suffit désormais de définir un objet graphique puis d'utiliser les méthodes fill et/ou stroke argumentées avec le nom de l'objet pour dessiner la forme correspondante autant de fois qu'on le désire.

Premier exemple

Cliquez une fois puis une deuxième fois dans le canevas ; les formes passent successivement à rouge puis à bleu.
Actualisez la page pour revenir à la couleur initiale (noir).

Le script correspondant

var canevas = document.querySelector('canvas'); // pour sélectionner le première zone canvas de la page var contexte = canevas.getContext('2d'); X = canevas.width ; Y = canevas.height; // créer un premier objet graphique : un rectangle var rectangle1 = new Path2D(); rectangle1.rect(110, 110, 50, 50); // créer un deuxième objet graphique : un cercle var cercle1 = new Path2D(); cercle1.arc(100,35, 25, 0, 2 * Math.PI); // dessiner ces objets en noir (couleur par défaut) contexte.stroke(rectangle1); contexte.fill(cercle1); var couleur ="red"; // changer couleur canevas.onclick = function() { contexte.fillStyle =couleur; contexte.strokeStyle =couleur; contexte.clearRect(0,0,X,Y); // redessiner en rouge puis en bleu contexte.stroke(rectangle1); contexte.fill(cercle1); couleur ="navy"; // changer couleur }

Commentaire

Il y a deux zones de dessin Canvas dans la page !
Plutôt que référencer un élément du DOM avec la méthode getElementById (qui oblige à identifier chaque élément) j'utilise la nouvelle API selectors avec les méthodes querySelector(sélecteur CSS) et querySelectorAll(sélecteur CSS)[indice].
Attention la première balise canvas d'une page a l'indice zéro ! Le premier élément d'un type de balise peut être référencé pa la méthode querySelector.

Grâce au constructeurs d'objets Path2D() on définit deux objets graphiques : un rectangle et un cercle.
On peut appliquer toutes les méthodes de trajet à l'objet Path2D pour définir la forme : moveTo(), rect(), arc(), quadratiCurveTo(), etc. Dans l'exemple on a utilisé les méthodes rect() et arc().
Ces formes sont dessinées trois fois mais avec des couleurs différentes (noire puis rouge puis bleu) en paramètrant les méthodes stroke() et/ou fill() avec l'objet.

Utiliser la syntaxe SVG

Deuxième bonne nouvelle : avec le constructeur Path2D() on peut utiliser la syntaxe SVG pour définir le chemin. Donc une seule instruction suffit pour définir une forme même très complexe.

Dans la zone de dessin Canvas ci-dessus il y a quatre formes colorées en noir.

Le script correspondant

	var canevas2 = document.querySelectorAll('canvas')[1]; // sélection deuxième canevas
	var contexte2 = canevas2.getContext('2d');
		
	var triangle = new Path2D('M10 10 L200 100 L200 200 Z');
	contexte2.fill(triangle);
		
	var rectangle2 = new Path2D( "M250 150 H400 V200 H250 Z");
	contexte2.fill(rectangle2);
		
	var toit_usine = new Path2D('M10 250 l20 -20 l20 20 l20 -20 l20 20 l 20 -20 l 20 20 l 20 -20 l20 20');
	contexte2.stroke(toit_usine);
		
	var carre = new Path2D('M10 300 h 80 v 80 h -80 Z');
	contexte2.fill(carre);

Commentaire

Le deuxième zone Canvas a l'indice 1 dans la collection (le premier canevas a l'indice zéro).

Notez que le script est très succinct grâce à l'emploi du constructeur Path2D ! Chaque objet Path2D est défini avec une seule instruction grâce à la notation SVG des chemins !

Les deux premiers chemins sont notés en absolu (les lettres L,H,V sont en majuscules).
Les deux derniers chemins sont notés en relatif (les lettres l,h,v sont en minuscules).
Je n'ai pas redéfini les couleurs de remplissage et de contour donc par défaut c'est noir !

Si vous ne comprenez rien à cette syntaxe vous devez visiter, dans le même site, le tutoriel "dessiner avec SVG" et plus précisément les pages "La balise Path" et "les chemins : notation en relatif" : dessiner à SVG

Restrictions

Attention dans la notation d'un trajet selon la syntaxe SVG les abscisses et ordonnées ne peuvent pas faire référence à des variables !
Donc si vous voulez définir un chemin en fonction de X et Y (largeur et hauteur du canevas) il faut utiliser les méthodes traditionnelles de Canvas(qui elles peuvent être paramétrées avec des variables).

Je m'explique ! Vous ne pouvez pas écrire, par exemple :

	...
	X = canevas.width; 	Y = canevas.height;
	...
	var quadratique1 = new Path2D("M 100 100 Q Y 5 X 100");
	var quadratique2 = new Path2D("M 100 100 Q Y 195 X 100");
	...

Cette syntaxe est fausse car elle reposé sur des variable (X et Y).

Par contre la syntaxe ci-dessous est correcte :

...
	contexte.moveTo(100,Y/2) ; 
	contexte.quadraticCurveTo(X/2,Y-20,X-100,Y/2); 
...

En effet la méthode quadraticCurveTo() (comme toutes les méthodes traditionnelles de trajet) peut être argumentée avec des variables !

Atelier

Essayez de reconstituer le code correspondant à cette belle balustrade classique.

Pour vous aider je vous donne quelques bribes du code (HTML & script) :

... <canvas width ="900" height="300" style ="width : 90% ; height : auto;" > </canvas> ... contexte3.fillStyle ="skyblue"; contexte3.fillRect(0,0, canevas3.width, canevas3.height); // fond du canevas : bleu ciel contexte3.fillStyle ="yellow"; contexte3.globalAlpha ="0.5"; var colonne = new Path2D("M 0,20 h120 v30 h-20 c-30,60 50,140 0,200 h20 v40 h-120 v-40 h20 c-50,-60 30,-140 0,-200 h-20 v-30 z"); for ... { contexte3.fill(colonne); // dessiner une colonne contexte3.translate(120,0) ; // translation } // fin for ...

HTML : dans le cadre du "responsive Web design" les dimensions d'affichage du canevas sont exprimées via le CSS.
Les valeurs des attributs width et height ne servent que pour calculer les dimensions et positions des formes dans le canevas.
Je consacre dans ce tuto toute une page sur les canevas adaptatifs.

J'utilise le constructeur path2D() pour définir une forme très complexe (avec des courbes de Bézier) pour définir une colonne de la balustrade.
J'utilise la syntaxe SVG pour définir le chemin avec notation en relatif.
Il faut dupliquer cette forme 8 fois. Il faut donc une boucle exécutée 8 avec dessin de l'objet "colonne" puis translation sur l'axe X.

Retour menu