Optimiser un fichier SVG/Chemin
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
modifierComme 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
modifierIl 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
modifierRectangle
modifierEn repartant sur l’exemple de rectangle du chapitre précédent, on peut appliquer la commande lineto
:
<path d="M 100,100 250,100 250,400 100,400"/>
<path d="M 100,100 L 250,100 250,400 100,400"/>
<path d="M 100,100 H250 V400 H100"/>
<path d="m 100,100 150,0 0,300 -150,0"/>
<path d="m 100,100 l 150,0 0,300 -150,0"/>
<path d="m 100,100 h150 v300 h-150"/>
Étoile
modifierEn 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 :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="test.svg">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="723"
id="namedview6"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-global="true"
inkscape:zoom="4.5092531"
inkscape:cx="77.224206"
inkscape:cy="50.589641"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg2">
<sodipodi:guide
orientation="1,0"
position="50,0"
id="guide3769" />
<sodipodi:guide
orientation="0,1"
position="0,50"
id="guide3767" />
<sodipodi:guide
orientation="0,1"
position="0,75"
id="guide3773" />
</sodipodi:namedview>
<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" />
</svg>
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
modifierDans 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À 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- ↑ 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. - ↑ Je n’ai jamais vu de chemin ne commençant pas par la commande
moveto
- ↑ 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…