Optimiser un fichier SVG/Chemin

Leçons de niveau 7
Une page de Wikiversité, la communauté pédagogique libre.
Début de la boite de navigation du chapitre
Chemin
Icône de la faculté
Chapitre no 6
Leçon : Optimiser un fichier SVG
Chap. préc. :Rectangle
Chap. suiv. :Style
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Optimiser un fichier SVG : Chemin
Optimiser un fichier SVG/Chemin
 », n'a pu être restituée correctement ci-dessus.

Avec le chemin, on va pouvoir commencer à voir des optimisations plus délicates. Parfois on ne pourra pas atteindre une situation optimale, il faudra choisir entre un code léger et un code lisible.

Généralités[modifier | modifier le wikicode]

Comme on l'a vu dans le chapitre précédent, on utilise l’élément chemin : path. Celui-ci ne possède qu’un seul attribut : d = "coordonnées du chemin".

Un chemin est composé d’autant de coordonnées que l’on souhaite. Ces coordonnées utilisent cinq commandes : moveto, lineto, curve, arc, closepath. Ces coordonnées sont séparées par un espace et une coordonnée est un couple de deux nombres (entiers ou décimaux) séparés par une virgule[1].

En SVG, les coordonnées sont données suivant les positions sur les axes x et y (dans cet ordre) et l'origine des axes se trouvent en haut à gauche du dessin. Ces axes peuvent être modifier par transformation, ce qui peut être pratique dans certains cas comme la représentation graphique d’une série de données (on fait alors coïncider l'origine des axes du dessin avec l'origine de l'axe du graphique).

Détails des commandes[modifier | modifier le wikicode]

Il existe cinq commandes (pour 20 lettres au total) :

  • moveto (M ou m) permet de placer le début du tracé, si on l’utilise plusieurs fois on commence donc un nouveau tracé dans un même chemin ; commande la plus polyvalente et la plus courante, elle se trouve toujours[2] au début du chemin.
  • lineto (L ou l, H ou h, V ou V) permet également de tracer des segments éventuellement en précisant la direction (horizontale ou verticale) ; commande très pratique et malheureusement peu utilisée qui permet d’alléger le code d’un tracé.
  • curve (C ou c et S ou s pour les courbes de Bézier cubique ; Q ou q et T ou t pour les courbes de Bézier quadratique) permet de tracer des courbes (w:courbes de Bézier).
  • arc (A ou a) permet de tracer des arcs d’ellipses (et donc de cercles)
  • closepath (Z ou z) permet de clore un tracé, elle s’utilise généralement en fin de tracé ; cette commande est courante mais engendre quelques subtilités sur les bordures que l’on détaillera au chapitre suivant[3].

Les capitales servent à indiquer que les coordonnées qui suivent sont absolues et les minuscules qu’elles sont relatives. Chaque commande existe donc en double et donc chaque tracé peut être exprimé d'au moins deux manières : <path d="M 100 100 300 300" /> équivaut à <path d="m 100 100 200 200" />.

Exemples[modifier | modifier le wikicode]

Rectangle[modifier | modifier le wikicode]

En repartant sur l’exemple de rectangle du chapitre précédent, on peut appliquer la commande lineto :

Début de l'exemple
Fin de l'exemple


Début de l'exemple
Fin de l'exemple


Étoile[modifier | modifier le wikicode]

En SVG, il existe une forme de base polygon qui est très similaire à l’élément path. Inkscape possède lui un outil spécifique pour « créer des étoiles et des polygones » qui crée un path très particulier. Pour cet exemple, on va partir du code généré par cet outil.

Avec Inkscape

On veut créer une étoile à 5 branches, centrée sur une zone de dessin de 100 par 100.

On utilise trois lignes de constructions : deux pour marquer le centre et une pour le sommet principal. On sélectionne l'outil « créer des étoiles et des polygones » (icône ), puis on choisi le mode étoile (icône ), on précise le nombre de sommets (5), le ratio des rayons (0,5), l'arrondi (0) et le hasard (0). On se place au centre (avec l'adhérence, Inkscape devrait proposer d’utiliser cette intersection), on clique et sans relâcher on tire jusqu'à l'intersection au-dessus. On enregistre le fichier et on l’ouvre avec un éditeur de texte classique.

On obtient alors le code brut suivant :

On se concentre sur l’élément path qui représente l'étoile :

  <path
     sodipodi:type="star"
     style="fill:#00ff00;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
     id="path3779"
     sodipodi:sides="5"
     sodipodi:cx="50"
     sodipodi:cy="50"
     sodipodi:r1="25"
     sodipodi:r2="12.5"
     sodipodi:arg1="-1.5707963"
     sodipodi:arg2="-0.9424778"
     inkscape:flatsided="false"
     inkscape:rounded="0"
     inkscape:randomized="0"
     d="M 50.000001,25 57.347316,39.887288 73.776413,42.274576 61.888206,53.862712 64.694631,70.225425 50,62.5 35.305368,70.225424 38.111794,53.862712 26.223587,42.274575 42.652684,39.887288 z" />

Ce code contient de nombreux arguments commençant par sodipodi: et inkscape:. Ceux-ci représente différents paramètres de la forme : son type, le nombre de côté, la position du centre en x et en y, les rayons, les arrondis, le hasard, etc. (ce qui correspond aux champs remplis lors de la création). Ils ne sont pas nécessaires pour la représentation puisque toutes les informations sur le tracé sont contenues dans l’argument d. On peut éventuellement se servir de ces arguments pour modifier rapidement la forme de l’étoile mais une fois la forme fixée ceux-ci sont complètement inutiles. Si avec l'éditeur de texte, on supprime ces arguments inutiles, on renomme la forme avec un id explicite et que l’on garde uniquement l’essentiel du style (vu qu’il n’y a pas de bordure : stroke:none, il est inutile de préciser le style de cette non-bordure), on obtient :

  <path
     id="ÉtoileVerte"
     style="fill:#00ff00"
     d="M 50.000001,25 57.347316,39.887288 73.776413,42.274576 61.888206,53.862712 64.694631,70.225425 50,62.5 35.305368,70.225424 38.111794,53.862712 26.223587,42.274575 42.652684,39.887288 z" />

On passe ainsi de 644 à 282 caractères sans aucune modification visuelle. On peut encore alléger un peu ce code, en améliorant les coordonnées du tracé. En effet, Inkscape utilise des nombres décimaux avec par défaut 8 chiffres significatifs et ajoute donc souvent des décimales supplémentaires. Ainsi, le premier point se trouve en 50.000001,25 au lieu de 50,25 ! De même pour un dessin sur une zone de 100 par 100, on peut se contenter de zéro à deux décimales.

Sans décimale, on a un code de 162 caractères et on peut distinguer quelques différences visuellement :

  <path
     id="ÉtoileVerte"
     style="fill:#00ff00"
     d="M 50,25 57,40 74,42 62,54 65,70 50,62 35,70 38,54 26,42 43,40 z" />

Avec une décimale, on a un code de 196 caractères et on peut difficilement apercevoir les différences :

  <path
     id="ÉtoileVerte"
     style="fill:#00ff00"
     d="M 50,25 57.3,39.9 73.8,42.3 61.9,53.9 64.7,70.2 50,62.5 35.3,70.2 38.1,53.9 26.2,42.3 42.7,39.9 z" />

Avec deux décimales, on a un code de 211 caractères et on ne peut remarquer les différences sans zoomer :

  <path
     id="ÉtoileVerte"
     style="fill:#00ff00"
     d="M 50,25 57.35,39.89 73.78,42.27 61.89,53.86 64.7,70.22 50,62.5 35.31,70.23 38.11,53.86 26.22,42.27 42.65,39.89 z" />

C’est là où l’auteur du dessin doit choisir entre différentes contraintes : la légèreté du code et sa lisibilité contre les besoins de précision visuelle. Quel que que soit ce choix, le poids de l’élément a été divisé au moins par deux, voire par trois ou quatre.

Une fois le niveau de précision choisi (sans décimale pour simplifier cet exemple), on peut chercher à écrire différemment ce code, par exemple en coordonnées relatives :

  <path
     id="ÉtoileVerte"
     style="fill:#00ff00"
     d="m 50,25 7,15 17,2 -12,12 3,16 -15,-8 -15,8 3,-16 -12,-12 17,-2 z" />

Représentation d’une série de données[modifier | modifier le wikicode]

Dans le cas de la représentation graphique d’une série de données, il peut être utile de faire coïncider l’origine des axes du dessin avec l’origine de l’axe du graphique.

Plusieurs tracés en un[modifier | modifier le wikicode]

À l’aide des commandes moveto et closepath, on peut faire plusieurs tracés (on dirait mieux des sous-tracés) dans un même chemin. Si on n’a pas besoin de différencier plusieurs chemins, autant les intégrer ensemble. Avec Inkscape, cela se fait très facilement à l’aide de la fonction Union (Ctrl++).

<path id="1" d="M 0,0 H 100 V 100 H 0 z"/>
<path id="2" d="M 0,200 H 100 V 300 H 0 z"/>

Équivaut à :

<path id="12" d="M 0,0 H 100 V 100 H 0 z M 0,200 H 100 V 300 H 0 z"/>

Cela permet ainsi d’alléger le code, surtout que cette opération est facilement réversible.

Références[modifier | modifier le wikicode]

  1. La virgule est optionnelle mais fortement recommandé pour la lisibilité :
    d="100,200 200,100 200,300"
    est plus lisible que :
    d="100 200 200 100 200 300"
    et cette seconde écriture n’est pas plus courte.
  2. Je n’ai jamais vu de chemin ne commençant pas par la commande moveto
  3. Je n’ai jamais réussi à trouver de différence entre les commandes Z et z, je suppose donc qu’il n’y en a pas…