Vous pouvez me contacter via Facebook pour questions & suggestions :
Page Facebook relative à mon site
Il s'agit des translations, des changements d'échelle et des rotations.
Translation : le point d’origine du canevas est déplacé.
Huit carrés de couleurs différentes décalés sauf le dernier.
Affichez la console du navigateur !
Le code HTML :
<canvas style ="width : 60% ; height :auto;" > </canvas >
La fonction JS :
À 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.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().
Le canevas 'responsive' fait 400 par 400.
Je dessine un premier carré rouge de 100 par 100 dans le coin haut gauche du canevas.
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).
On peut aussi changer l'orientation du contexte ou en d'autres termes effectuer une rotation des axes.
La méthode rotate() est argumentée par un angle exprimé en radians !
Ainsi si vous dessinez un carré après une rotation de 45° des axes il apparaitra en fait tel un losange !
Trois formes dans le canevas ci-dessus : un carré rouge puis un losange jaune et enfin un carré vert !
Le canevas 'responsive' fait 400 par 300.
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é.
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().
La première forme a une inclinaison verticale, la deuxième une torsion horizontale,
la troisième une inclinaison verticale et horizontale.
Le canevas est identifié "canevas4" et fait 500 par 400.
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.
Il s'agit d'un bon exemple de rotation après un changement d'origine.
Ci-dessous un document HTML qui contient une 'toile' affichant le cadran d'une montre avec un aiguille (la trotteuse).
Le canevas fait 300 par 300 et est identifié "canevas".
ctx.translate(X/2,Y/2) : à partir du moment que vous envisagez des rotations il est préférable que l'origine du
canevas soit son centre.
Marquage des heures :
Marquage des minutes :
Affichage de l'aiguille (trotteuse) :
La méthode rotate() est argumentée par un angle en radians.
Les transformations sont souvent à la base des animations.
Ces méthodes vont être incontournables à partir du moment où l'on commence à créer des dessins complexes ;
avec succession de différents contextes.
Cette méthode sauvegarde l'état du canevas dans sa globalité.
La méthode save() peut être invoquée autant de fois que nécessaire.
Cette commande rétablit le plus récent contexte sauvegardé (celui en haut de la pile).
Le canevas fait 300 par 300.
Le premier rectangle est noir et placé en haut à gauche.
Donc on a sauvegardé un état 0 puis un état 1 et ensuite on restaure l'état 1 puis l'état 0 : deux "save()" et deux "restore()".
Canvas : les transformations
Les différentes méthodes que nous allons employer dans les exemples de ce chapitre :
Translations
Exemple
Le code de la page
Les attributs width & height sont absents de l'instruction HTML. Donc quelles sont les dimensions de ce canevas ?
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
Les nouveautés dans ce script :
contexte.fillRect(0,0,cote,cote) : dessin d'un carré au point 0,0 mais de la nouvelle origine
Changement d'échelle
Exemple
Le code correspondant
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 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)
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
Principes
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.Exemple
Le code correspondant
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();
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()
Cette méthode prend 6 arguments :
Exemple de script basé sur cette méthode
Le code
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();
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().
Un cadran de reveil
Le document HTML
Le code du document
Le script
var canevas = document.querySelector("#canevas");
var ctx = canevas.getContext("2d");
var X =canevas.width;
var Y =canevas.height;
ctx.translate(X/2,Y/2);
ctx.strokeStyle = "gold";
ctx.lineWidth = 4;
// marques heures
for (var i=0;i<12;i++)
{
ctx.beginPath();
// un trait tous les 30°
ctx.rotate(Math.PI/180 * 30);
ctx.moveTo(80,0);
ctx.lineTo(100,0);
ctx.stroke();
}
// marques minutes
ctx.lineWidth = 2;
for (i=0;i<60;i++)
{
ctx.beginPath();
// un trait tous les 6°
ctx.rotate(Math.PI/180 *6);
ctx.moveTo(90,0);
ctx.lineTo(100,0);
ctx.stroke();
}
// trotteuse
ctx.strokeStyle ="black";
ctx.lineWidth =3;
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(0,-100);
ctx.stroke();
Analyse du script
Il faut créer 12 traits : un trait tous les 30 degrés (360 /12).
Il faut créer 60 traits plus courts et moins épais : un trait tous les 6 degrés (360/60).
Il faut changer la couleur et l'épaisseur de contour, dessiner un trait à partir du centre du canevas.
Pour convertir des degrés en radians la formule est : Math.PI/180 *degrés.
Transformations et animations
Dans le chapitre 23, la trotteuse s'anime et fait un tour en une minute :
Des animations sophistiquées
Bien comprendre les méthodes save() & restore()
save()
Chaque invocation de la méthode save() ajoute une copie de l'état courant du canevas en haut de la pile.
Cet état courant du canevas est composé :
restore()
Cette méthode peut être évoquée autant de fois qu'il y a eu de commmandes save().
Un document HTML contenant un canevas
Le script
function dessin()
{
var ctx = document.getElementById("canvas").getContext("2d");
ctx.fillRect(0,0,150,50);
ctx.save();
// Sauvegarde l'état initial : l'origine est le coin haut gauche et couleur est noir
ctx.translate(150,150) ;
// origine devient le centre du canevas
ctx.fillStyle = "grey";
ctx.fillRect(0,0,120,60);
ctx.save();
// Sauvegarde l'état actuel (translation et couleur est grey)
ctx.rotate(-Math.PI/180*90);
ctx.fillStyle = "purple";
ctx.fillRect(0,0, 90, 30);
// Dessine un rectangle avec translation & rotation
ctx.restore();
// Restaure l'état précédent : translation & couleur de fond est grey
ctx.fillRect(50,100,50,25);
ctx.restore();
// Restaure l'état initial : l'origine est coin haut gauche, couleur : noir
ctx.fillRect(50,200,60,30);
}
dessin();
Analyse du script
Le deuxième rectangle est gris et placé dans le centre du canevas du fait de la translation.
Le troisième rectangle est violet sa largeur est orienté vers le haut du fait de la rotation de 90% dans le
sens contraire des aiguilles d'une montre.
Le quatrième rectangle est gris et positionné à 200,250 du fait de la translation ; mais plus de rotation.
Le cinquième rectangle est noir et positionné à 50,200 du fait du retour à l'état initial (plus de translation).