SVGround : cours SVG

Les transformations

Il y a cinq transformations possibles en SVG : la translation (translate), la rotation (rotate), le changement d’échelle (scale), la transformation par inclinaison de l’axe des abscisse (skewX) et celle par inclinaison de l’axe des ordonnées (skewY).
Cependant, on utilise qu’un seul attribut pour effectuer les transformations : l’attribut transform.
La syntaxe pour effectuer un transformation est : transform="mot-clé(valeur1, valeur2, valeurn)".

La translation

La translation requiert deux paramètres : le premier est la translation sur l’axe des abscisses et le second sur l’axe des ordonnées. Effectuons une translation pour placer un cercle au milieu de la zone de dessin :

< Translation d’un cercle avec SVG ]]>
Translation d’un cercle avec SVG

Ici, il n’y a pas d’attributs cx et cy : SVG considère qu’ils valent 0. Le centre du cercle a été déplacé au point 200,150. On aurait pu avoir le même effet en mettant cx="200" et cy="150" ce qui est plus logique, mais c’est juste pour vous montrer le principe et ne vous inquietez pas, ça nous servira dans très peu de temps :).

La rotation

La rotation prend un paramètre : l’angle de rotation en degrés. Il peut bien sur être négatif, supérieur à 360, etc. On aimerait faire tourner un rectangle de 30° :

< Rotation d’un rectangle avec SVG ]]>
Rotation d’un rectangle avec SVG

Ce n’est pas vraiment le résultat attendu. Et pour cause : ce n’est pas seulement le rectangle qu’on a tourné : c’est toute la zone de dessin ! Cliquez sur « rotation » pour voir l’effet d’une rotation.

Rotation d’un rectangle avec SVG

C’est donc toute la zone de dessin qui subit une rotation autour de son point d’origine de coordonnées 0,0. C’est d’ailleurs la même chose avec la translation. Heureusement, il est tout à fait possible de spécifier le centre de rotation avec un second et un troisième paramètre. Le second est l’abscisse du centre de rotation et le troisième est l’ordonnée. Par exemple, sur un carré :

< Rotation d’un carré sur lui même avec SVG ]]>
Rotation d’un carré sur lui même avec SVG

Bien sur, les longueurs n’ont pas été prises au hasard : le point 200,150 est le centre du carré. Notez que la rotation se fait dans le sens indirect, c’est à dire dans le sens des aiguilles d’une montre.

Le changement d’échelle

Le changement d’échelle est réalisé grâce à scale. Il prend deux paramètres : le premier est le changement d’échelle sur les abscisses et le second sur les ordonnées. Dans le cas ou seul le premier paramètre est spécifié, le second prend la même valeur.

< Changement d’échelle avec SVG ]]>
Changement d’échelle avec SVG

Il n’y a rien à faire, notre rectangle n’est pas resté en place… En fait, il s’est encore passé la même chose que précédemment : c’est la zone de dessin qui a été transformé, pas seulement le rectangle. Toutes les coordonnées ont été multipliées par 2. Ainsi, le point d’origine qui se trouvait à 40,40 se retrouve à 80,80. La taille de la bordure (stroke-width) a elle aussi été multipliée par deux. Cliquez sur le boutton pour voir comment fonctionne scale.

Schéma d’un changement d’échelle avec SVG

On peut aussi se servir de scale pour « étirer » une forme vers le bas ou vers la droite :

< Scale peut aussi servir à étirer des objets ]]>
Scale peut aussi servir à étirer des objets

Mais on peut aussi mettre des valeurs négative pour, par exemple, faire de la symétrie. Pour un symétrie centrale on fera transform="scale(-1,-1)"; pour une symétrie axiale : transform="scale(1,-1)" ou transform="scale(-1,1)".
Si on met zéro pour une des deux valeur, la figure ne s’affichera pas puisqu’un produit par 0 vaut toujours 0 ! Notez aussi qu’on utilise le point pour séparer les unités des dixièmes et non la virgule. Nous verrons plus tard qu’il est possible, comme pour la rotation, de faire un changement d’échelle centré.

Les transformations skewX et skewY

Les commandes skewX et skewY permettent, comme les autres transformations, une transformation de la zone de visualisation en effectuant une rotation des coordonnées x pour skewX et y pour skewY de la valeur de l’angle indiqué. Prenons ces schémas :

La transformation skewX en SVG

Dans cet exemple, les lignes verticales sont inclinées à 45° par rapport à la normale car on a appliqué un skewX(45).

La transformation skewY en SVG

Là, ce sont les axes horizontaux qui ont été inclinés de 30° par un skewY(30).

Essayez avec une valeur de 90° : on obtient plus qu’une seule ligne. Avec 180°, on revient à la position de départ et un skewY(20) et donc égal à un skewY(200) (180 + 20). Il est bien sur possible de spécifier des valeurs négatives et décimales. Par exemple -57275.256 est valide. Essayons avec un cercle :

< skewX et skewY sur un cercle ]]>
skewX et skewY sur un cercle

Les enchaînements de transformations

Il est possible d’enchaîner plusieurs transformations dans un seul attribut, ce qui peut s’avérer très utile. On peut donc faire subir une translation puis une rotation à un objet, ou une transformation skewX suivi d’une transformation skewY pour donner un effet 3D. La syntaxe est :
transform="mot-clé1(valeurs) mot-clé2(valeurs) mot-clén(valeurs)".
Essayons de changer d’échelle à un carré, de le déplacer vers la droite et le bas, de le faire pivoter et d’appliquer un skewX, tout cela en décomposant l’enchaînement des transformations :

< Multiples transformations sur un carré ]]>
Multiples transformations sur un carré

On remarque d’ores et déjà plusieurs choses à première vue étranges. On a effectué une translation de 80 vers la droite et 50 vers le bas et notre carré se retrouve au centre de la zone de dessin alors que cette zone de dessin fait à l’origine 400 pixels de largeur et 300 pixels de hauteur. De même, la rotation s’est faite par rapport au coin haut gauche de notre carré, et non pas par rapport au coin haut gauche de notre zone svg.

L’explication est en fait très simple : on sait que c’est notre zone de dessin qui subit les transformations. Or, entre 2 transformations elle ne retrouve pas sa forme initiale. Ainsi, après le changement d’échelle (transform="scale(2.3)"), notre zone de dessin ne fait plus 400×300 pixels mais 920×390 (les coéfficients sont mulitpliés par 2,3) ! Cependant, on voit toujours notre dessin dans une boîte de 400 pixels de largeur et 300 pixels de hauteur. Une translation de 200 vers la droite et 200 vers le bas ferait sortir notre carré de la zone visible. Il se passe la même chose pour la rotation, mais rien ne vaut un schéma pour visualiser ces enchaînements de transformations.

Les enchaînements de transformation en SVG

La rotation s’est donc bien faite par rapport au point d’origine mais ce point avait auparavant été déplacé par la translation.

Changement d’échelle centré

Grâce aux enchaînements de transformations, on va pouvoir effectuer un changement d’échelle centré. La formule est assez simple :

Avec un changement d’échelle égal à n :
transform="translate(-centreX*(n-1), -centreY*(n-1)) scale(n)"

Essayons avec une ellipse :

< Changement d’échelle centré en SVG ]]>
Changement d’échelle centré en SVG

Il existe encore une transformation, mais nous ne l’étudierons pas : il s’agit de la transformation matrix. C’est une transformation générique qui fait appel au calcul matriciel pour faire tout ce que l’on a pu faire avec translate, rotate, scale, skewX et skewY. Jusqu’ici, nous avons écrit un code assez verbeux, notamment au niveau des styles CSS. Le prochain chapitre traite de l’optimisation du code XML et CSS.

Les formes de base
Comment bien structurer un document SVG