Accueil

Traduction

Tutoriel Canvas - sommaire

Tutoriel Canvas - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Canvas : les transformations

Il s'agit des translations, des changements d'échelle et des rotations.

Translations

Translation : le point d’origine du canevas est déplacé.

Exemple

Huit carrés de couleurs différentes décalés sauf le dernier.

Affichez la console du navigateur !

Le code de la page

Le code HTML :

<canvas style ="width : 60% ; height :auto;" > </canvas >
Les attributs width & height sont absents de l'instruction HTML. Donc quelles sont les dimensions de ce canevas ?

La fonction JS :

function script1()
{
	canevas = document.querySelector('canvas'); 
	contexte = canevas.getContext('2d');
	var X =canevas.width;
	var Y =canevas.height;
	console.log(X); 
	console.log(Y); 
	var delta = 20; 
	var cote = 50;
	var rouge = 255; var vert = 0; var bleu = 0; 
	var couleur;;
	contexte.globalAlpha = 0.5; // 50% opacité pour tous les tracés futurs
	for (i=1; i<=7; i++)
	{
		rouge-=30 ; vert+=30; bleu+=30;
		couleur = "rgb("+ rouge+","+vert+","+bleu+")" ; 
		contexte.fillStyle = couleur ;
		contexte.fillRect(0,0,cote,cote) ; 
		contexte.translate(delta,delta) ; // déplacement origine pour rectangle suivant
	} // fin for 
		
	contexte.resetTransform(); 
	contexte.fillRect(X-cote,0,cote,cote); 
}
script1(); 	//appel de la fonction	

À chaque passage dans la boucle le contenu de "couleur" (qui contient un code RGB) change. L'intensité de rouge diminue, celle de vert et de bleu augmentent.

À chaque passage dans la boucle le point d'origine est décalée de 20 sur la droite et en bas : contexte.translate(delta,delta)
contexte.fillRect(0,0,cote,cote) : dessin d'un carré au point 0,0 mais de la nouvelle origine

contexte.resetTransform() : annulation des transformations donc le dernièr carré est bien dessiné à partir du bord haut du canevas conformément aux arguments x,y de FillRect().

Changement d'échelle

Exemple

Le code correspondant

Le canevas 'responsive' fait 400 par 400.
La fonction JS :

function script2()
{
	canevas = document.querySelectorAll('canvas')[1]; 
	contexte = canevas.getContext('2d');
	contexte.fillStyle ='red'; 
	contexte.fillRect(0,0,100,100);
	contexte.save(); //sauvegarde état initial canevas
	contexte.scale(2,2);
	contexte.fillStyle ='green'; 
	contexte.fillRect(100,100,100,100);
	contexte.restore(); //restauration état intial canevas
	contexte.fillStyle ='yellow';
	contexte.fillRect(100,100,50,50);
}
script2(); //appel fonction

Je dessine un premier carré rouge de 100 par 100 dans le coin haut gauche du canevas.
Je sauvegarde cet état initial du canevas avant une transformation : canevas.save()
J'applique au canevas un changement d'échelle pour les deux axes : contexte.scale(2,2)

Je dessine un carré vert (fillRect(100,100,100,100) mais comme l'échelle a été doublée pour les deux axes ce carré a son arête supérieure gauche au point 200,200 (et non pas 100,100) et des côtés de 200 (et non pas 100).
contexte.restore() : restauration de l'état initial sauvegardé donc annulation du changement d'échelle.
fillRect(100,100,50,50) : le carré jaune fait bien 50 par 50 et est bien positionné par rapport au point 100,100.

Rotation de formes

On peut aussi changer l'orientation du contexte ou en d'autres termes effectuer une rotation des axes.

Principes

La méthode rotate() est argumentée par un angle exprimé en radians !
Cette méthode fait pivoter les axes X et Y du repère dans le sens des aiguilles d'une montre autour du point d'origine.
Observez le schéma ci-dessous qui est plus explicatif qu'un long discours.

Ainsi si vous dessinez un carré après une rotation de 45° des axes il apparaitra en fait tel un losange !

Exemple

Trois formes dans le canevas ci-dessus : un carré rouge puis un losange jaune et enfin un carré vert !

Le code correspondant

Le canevas 'responsive' fait 400 par 300.
La fonction JS :

function script3()
{                          
	canevas = document.querySelectorAll('canvas')[2]; 
	contexte = canevas.getContext('2d');
	contexte.fillStyle ='red'; 
	contexte.fillRect(0,0,100,100);
	contexte.save(); // sauvegarde de l'état initial
	contexte.rotate(Math.PI/180 *45); // rotation du canevas de 45° 
	contexte.fillStyle ='yellow'; 
	contexte.fillRect(200,0,100,100);
	contexte.restore(); // restauration état initial donc annulation rotation
	contexte.fillStyle ='green'; 
	contexte.fillRect(300,100,100,100);
}
script3();

On retrouve l'instruction contexte.save() pour sauvegarder l'état initial (avant rotation de l'axe). Cette instruction est indispensable si une restauration est envisagée. En effet seul un état sauvegardé peut être restauré.
contexte.rotate(Math.PI/180 *45): orientation du canevas de 45°.
On dessine ensuite un carré jaune (rectangle avec largeur = hauteur) qui compte tenu de la rotation apparait tel un losange.
contexte.restore() : on restaure l'état précédent donc on annule la rotation du contexte.
La troisième forme (remplie de vert) apparaît bien comme un carré puisque la rotation des axes a été annulée.

La méthode transform()

La Librairie Canvas ne propose pas de méthode skew()(à la différence de CSS3 et de SVG) pour appliquer un inclinaison (torsion) à une forme. On ne peut que regretter cette lacune. Mais vous pouvez parvenir au même résultat avec la méthode transform().

    Cette méthode prend 6 arguments :
  1. mise à l’échelle dans le plan horizontal
  2. inclinaison dans le plan horizontal
  3. torsion dans le plan vertical
  4. mise à l’échelle dans le plan vertical
  5. déplacement horizontal
  6. déplacement vertical

Exemple de script basé sur cette méthode

La première forme a une inclinaison verticale, la deuxième une torsion horizontale, la troisième une inclinaison verticale et horizontale.

Le code

Le canevas est identifié "canevas4" et fait 500 par 400.
La fonction JS :

function script4()
{
	let canevas = document.getElementById('canevas4');
	let ctx = canevas.getContext('2d');
	var modele = new Path2D();
	modele.rect(0, 0, 100, 100);
	ctx.transform(1,0,0.5,1,0,0);
	ctx.fill(modele);

	ctx.resetTransform(); 
	ctx.transform(1,0.5,0,1,120,120);
	ctx.fill(modele);

	ctx.setTransform(1,0.5,0.5,1,240,240);
	ctx.fill(modele);
}
script4();

Je définis un modèle de carré (100 par 100) nommée "modele" que je duplique trois fois avec à chaque fois torsion et translation.
Notez que dans les trois clonages du modèle les arguments 1 et 4 sont à 1 (pas de changement d'échelle).
Pour la dernière copie de modèle je remplace avantageusement les commandes resetTransform() & transform() par une seule instruction : setTransform().

Synthèse

En combinant le constructeur Path2D et les transformations, il est possible de réaliser en quelques lignes de code un superbe graphique.
Ci-dessous un document HTML contenant un canevas.

Etes vous capable de reconstituer le script qui remplit le canevas de cette page ?
Je définis un modèle de cercle puis je le duplique 12 fois avec à chaque fois une opacité plus grande et un changement d'échelle qui donne de la profondeur donc un effet 3D.
Donc il y a une boucle pour dupliquer 12 fois le modèle, incrémenter l'opacité, changer d'échelle (1.1 à chaque fois pour chaque axe).
Le script est donc très court.