Tutoriel pour apprendre à utiliser le format SVG

On dessine

Maurice Chavelli

Dans ce troisième article consacré au SVG, je vais un peu détailler les possibilités de dessins. J'ai déjà présenté des bases dans ce tutoriel. Je vais maintenant aller plus loin et montrer les belles possibilités qui nous sont offertes.

Commentez

- Titre : Tutoriel pour apprendre à utiliser le format SVG

- Auteur : Maurice Chavelli

- Parution : 14 août 2019

- Licence : Copyright ® 2019 Maurcie Chavelli. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Des lignes

- I-A. Simple ligne

- I-B. Polyligne

- I-C. Terminaison de ligne et liaison

- II. Des formes

- II-A. Rectangle

- II-B. Cercle et ellipse

- II-C. Polygone

- III. Les chemins (path)

- III-A. Les bases

- III-B. Les raccourcis

- III-C. Les arcs elliptiques

- III-D. Les courbes de Bézier

- IV. Un exemple

- V. Un autre exemple

- VI. Conclusion

- VII. Remerciements

I - Des lignes

I-A - Simple ligne

La base du dessin c'est la ligne et SVG est bien équipé dans le domaine. On a vu qu'on dispose de la balise line. Par défaut on a stroke: none, ce qui signifie qu'une ligne n'est pas visible par défaut ! Donc si vous prévoyez ce code :

<line x1="20" y1="20" x2="100" y2="150"/>

Vous ne verrez rien…

Donc il faut au minimum définir la couleur (stroke) :

<line x1="20" y1="20" x2="100" y2="150" stroke="red" />

On définit le point d'origine (x1 et y1) et le point d'arrivée (x2 et y2). Je rappelle que l'origine des axes se trouve dans le coin supérieur gauche (ce qui est classique).

On peut ensuite styliser cette ligne en changeant l'épaisseur et la continuité (pointillés) :

1. <svg height="400" width="400">

2. <style>

3. line {

4. stroke: blue;

5. stroke-dasharray: 8, 4;

6. stroke-width: .2rem;

7. }

8. </style>

9. <line x1="20" y1="20" x2="100" y2="150"/>

10. </svg>

Les deux valeurs pour les pointillés repèrent la partie pleine et la partie vide (gap).

On peut aussi jouer sur l'opacité d'une ligne avec la propriété stroke-opacity :

1. <line x1="20" y1="50" x2="100" y2="50" style="stroke: blue; stroke-width: 25;"/>

2. <line x1="20" y1="20" x2="100" y2="120"style="stroke-opacity: 0.4; stroke: red; stroke-width: 25;"/>

On peut faire beaucoup de choses avec des lignes, mais ça devient vite laborieux.

I-B - Polyligne

Si on a une succession de lignes, plutôt que de dessiner les lignes les unes après les autres, on utilise une polyligne :

1. <svg height="400" width="400">

2. <style>

3. polyline {

4. stroke: green;

5. stroke-width: 10;

6. fill: none;

7. }

8. </style>

9. <polyline points="60 140, 100 50, 55 100, 55 10, 25 100"/>

10. </svg>

J'ai prévu sans remplissage () sinon on obtient ce résultat :

On peut évidemment choisir aussi la couleur de remplissage en fixant la couleur au lieu de none.

I-C - Terminaison de ligne et liaison

Quand on trace des lignes (et polylignes) les extrémités sont avec des angles à 90° :

On peut utiliser la propriété stroke-linecap (la valeur par défaut est butt) pour changer ce comportement :

1. <svg height="400" width="400">

2. <style>

3. line {

4. stroke: purple;

5. stroke-width: 20;

6. }

7. </style>

8. <line x1="20" y1="20" x2="140" y2="20" stroke-linecap="butt"/>

9. <line x1="20" y1="50" x2="140" y2="50" stroke-linecap="round"/>

10. <line x1="20" y1="80" x2="140" y2="80" stroke-linecap="square"/>

11. </svg>

Vous pouvez remarquer que les valeurs round et square prolongent la ligne au-delà des valeurs de référence.

Pour la jonction entre deux lignes, on a la propriété stroke-linejoin :

1. <svg height="400" width="400">

2. <style> polyline {

3. stroke: green;

4. stroke-width: 10;

5. stroke-linecap: round;

6. stroke-linejoin: round;

7. fill: none; }

8. </style>

9. <polyline points="60 140, 100 50, 55 100, 55 10, 25 100"/>

10. </svg>

II - Des formes

II-A - Rectangle

J'ai déjà montré comment dessiner un rectangle dans le premier article. On peut évidemment styliser à loisir :

1. <svg height="400" width="400">

2. <rect x="20" y="20" width="50" height="90" style="fill-opacity: 0.3"/>

3. <rect x="40" y="10" width="80" height="40" style="fill: none; stroke: black;"/>

4. <rect x="10" y="40" width="125" height="100" style="fill: #0000ff; stroke: blue; stroke-width: 10; stroke-opacity: 0.2; fill-opacity: 0.3"/>

5. <rect x="50" y="70" width="135" height="50" style="fill: yellow; fill-opacity: 0.5; stroke: green; stroke-width: 2; stroke-dasharray: 5 2"/>

6. </svg>

On peut arrondir les coins en précisant le rayon :

<rect x="10" y="10" width="125" height="70" rx="20" style="fill: none; stroke: rgb(118, 19, 163); stroke-width: 10"/>
<rect x="10" y="110" width="125" height="70" rx="20" ry="40" style="fill: none; stroke: rgb(16, 207, 80); stroke-width: 10"/>

II-B - Cercle et ellipse

J'ai également montré comment tracer cercles et ellipses, voici un exemple :

<circle cx="50" cy="50" r="40" style="stroke: rgb(160, 189, 32); stroke-width: 7; fill: none;"/>
<circle cx="70" cy="80" r="60" style="stroke: rgb(201, 20, 20); stroke-width: 7; fill: none; stroke-opacity: 0.4"/>
<ellipse cx="130" cy="80" rx="80" ry="40" style="fill: blue; fill-opacity: 0.2"/>

II-C - Polygone

Pour un polygone, on définit tous les points :

<polygon points="100,10 40,198 190,78 10,78 160,198" style="fill: rgb(163, 126, 194); stroke: blue; stroke-width: 7"/>

On gère évidemment tous les styles concernant le trait et le remplissage comme on l'a vu plus haut.

On peut modifier la règle de remplissage :

<polygon points="100,10 40,198 190,78 10,78 160,198" style="fill-rule: evenodd; fill: rgb(163, 126, 194); stroke: blue; stroke-width: 7"/>

III - Les chemins (path)

III-A - Les bases

Toutes les formes de base vues ci-dessus sont pratiques et doivent être utilisées en priorité. Mais arrive un moment où elles ne sont pas suffisantes, on peut alors utiliser un chemin (path).

Un chemin est une succession de lignes, d'arcs et de courbes. On peut définir le trait comme on l'a déjà vu. Voici un premier exemple :

<path d="M 10 10 L 200 30" style="stroke-width: 10; stroke: rgb(231, 163, 37); fill: none;"/>

Un chemin doit commencer par un moveto (M) suivi des coordonnées de départ. Imaginez cela comme le fait de placer le stylo sur le point. Ensuite on place des lineto (L) avec des coordonnées, là on déplace le stylo.

On place autant de lineto qu'on veut :

<path d="M 10 10 L 200 30 L 200 80" style="stroke-width: 10; stroke: rgb(231, 163, 37); fill: none;"/>

Si vous insérez un nouveau moveto vous démarrez un sous-chemin :

<path d="M 10 10 L 200 30 M 220 30 L 200 80" style="stroke-width: 10; stroke: rgb(231, 163, 37); fill: none;"/>

Vous pouvez provoquer la fermeture du chemin avec un closepath (Z) :

<path d="M 10 10 L 200 30 L 200 80 Z" style="stroke-width: 10; stroke: rgb(231, 163, 37); fill: none;"/>

On a vu jusque là des valeurs absolues pour les coordonnées de déplacement, on peut aussi utiliser des valeurs relatives en utilisant des minuscules :

<path d="M 10 10 L 200 30 m 20 0 l -20 50" style="stroke-width: 10; stroke: rgb(231, 163, 37); fill: none;"/>

III-B - Les raccourcis

On peut simplifier la syntaxe pour les lignes horizontales (H) et verticales (V) :

<path d="M 30 20 h 200 v 60 h -200 z" style="stroke-width: 10; stroke: rgb(231, 163, 37); fill: none;"/>

III-C - Les arcs elliptiques

Les arcs elliptiques sont des morceaux d'ellipse. Voici un exemple :

<path d="M 320 150 A 150 120, 0, 1, 0, 2 152" style="stroke-width: 4; stroke: red; fill: none;"/>

On utilise l'abréviation A suivie des deux rayons (x et y), puis de la rotation de l'axe x, puis d'autres valeurs qu'il serait laborieux de décrire. Je suppose que vous n'allez jamais dessiner un arc elliptique directement en partant du code ! On atteint ici les limites entre le fait de vouloir tout coder directement et utiliser un éditeur graphique.

III-D - Les courbes de Bézier

Vous utiliserez plus souvent des courbes de Bézier que des arcs elliptiques, parce que vous pourrez plus facilement dessiner tout ce que vous voulez. Là, ça devient carrément périlleux de se lancer dans le codage direct et on passe obligatoirement par un éditeur graphique.

Vous pouvez utiliser Inkscape comme je vous l'ai conseillé, ou un des nombreux éditeurs en ligne comme SVG-edit :

Voici un fichier SVG créé en quelques clics avec Inkscape :

1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>

2. <svg

3. xmlns:dc="http://purl.org/dc/elements/1.1/"

4. xmlns:cc="http://creativecommons.org/ns#"

5. xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

6. xmlns:svg="http://www.w3.org/2000/svg"

7. xmlns="http://www.w3.org/2000/svg"

8. id="svg8"

9. version="1.1"

10. viewBox="0 0 159 106"

11. height="400"

12. width="600">

13. <defs

14. id="defs2" />

15. <metadata

16. id="metadata5">

17. <rdf:RDF>

18. <cc:Work

19. rdf:about="">

20. <dc:format>image/svg+xml</dc:format>

21. <dc:type

22. rdf:resource="http://purl.org/dc/dcmitype/StillImage" />

23. <dc:title></dc:title>

24. </cc:Work>

25. </rdf:RDF>

26. </metadata>

27. <g

28. transform="translate(0,-191)"

29. id="layer1">

30. <path

31. id="path836"

32. d="m 15.9,276 c 0,0 -21.2,-48 15.9,-43 37.1,6 31.8,16 47.7,6 15.9,-11 79.5,32 31.5,37 -47.4,5 -95.1,0 -95.1,0 z"

33. style="fill:#8bc200;stroke:#8a0000;stroke-width:1.59;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />

34. </g>

35. </svg>

IV - Un exemple

Voici le code d'un exemple, récupéré dans une bibliothèque en ligne, que j'ai nettoyé de plein de choses inutiles :

1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>

2. <svg xmlns="http://www.w3.org/2000/svg">

3. <path

4. d="M432,8H80C66.766,8,56,18.766,56,32v456c0,13.234,10.766,24,24,24h352c13.234,0,24-10.766,24-24V32

5. C456,18.766,445.234,8,432,8z"

6. style="fill:#FF4F19;" />

7. <path

8. d="M95.781,8H80C66.766,8,56,18.766,56,32v456c0,13.234,10.766,24,24,24h15.781V8z"

9. style="fill:#E3001E;" />

10. <path

11. d="M400,0h-80c-4.418,0-8,3.582-8,8v119.996c0,2.883,1.547,5.543,4.055,6.961

12. c2.508,1.422,5.586,1.391,8.063-0.102L360,113.325l35.883,21.531c1.266,0.762,2.695,1.141,4.117,1.141

13. c1.359,0,2.719-0.344,3.945-1.039c2.508-1.418,4.055-4.078,4.055-6.961V8C408,3.582,404.418,0,400,0z"

14. style="fill:#5D647F;" />

15. <path

16. d="M96,480c-4.422,0-8-3.582-8-8V48c0-4.418,3.578-8,8-8s8,3.582,8,8v424 C104,476.418,100.422,480,96,480z"

17. style="fill:#C10019;" />

18. <path

19. d="M355.781,344h-0.572c-0.071-0.272-0.084-0.545-0.17-0.816L309.76,199.801

20. c5.679-0.948,10.021-5.85,10.021-11.801c0-6.629-5.375-12-12-12h-64c-6.625,0-12,5.371-12,12c0,5.951,4.343,10.853,10.021,11.801

21. l-45.279,143.383c-0.086,0.271-0.1,0.544-0.17,0.816h-0.572c-6.625,0-12,5.371-12,12s5.375,12,12,12h32c6.625,0,12-5.371,12-12

22. c0-5.951-4.342-10.853-10.021-11.801L238.665,316h74.231l8.905,28.199c-5.678,0.948-10.021,5.85-10.021,11.801

23. c0,6.629,5.375,12,12,12h32c6.625,0,12-5.371,12-12S362.406,344,355.781,344z M248.77,284l26.269-83.184

24. c0.086-0.271,0.1-0.544,0.17-0.816h1.144c0.071,0.272,0.084,0.545,0.17,0.816L302.792,284H248.77z"

25. style="fill:#FFCD00;" />

26. </svg>

On voit que le dessin est composé de cinq chemins, voici la vue éclatée :

On voit qu'on pourrait simplifier le fichier en utilisant plutôt un rectangle aux coins arrondis pour la grosse partie orange, on peut donc remplacer le premier chemin par ce code :

1. <rect

2. style="fill:#ff4f19;"

3. id="rect28"

4. width="396"

5. height="506"

6. x="55"

7. y="8"

8. ry="25.1"

9. rx="27.1" />

On peut aussi se contenter d'un simple trait pour la partie verticale fine.

Par contre, les trois autres éléments nécessitent un chemin.

C'est l'inconvénient des éditeurs, ils ne permettent pas toujours de faire des choses simples, mais on leur pardonne parce qu'ils sont vraiment performants !

Le fichier fait moins de 2 Ko ce qui est très peu. Et on dispose d'une image qui peut s'adapter à toutes les résolutions !

La même image en PNG au format 512*512 fait 5 Ko et elle est bien moins adaptable :

En plus, il est impossible d'agir avec du style ou un script sur des éléments de l'image. On doit la prendre globalement telle qu'elle est.

On a donc tout intérêt à utiliser le format SVG !

V - Un autre exemple

Sur le même site, j'ai trouvé un joli crayon, voilà le code nettoyé :

1. <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512.096 512.096" >

2. <path style="fill:#E6BE94;" d="M296.158,0h-80c-4.418,0-8,3.582-8,8v376l44.282,125.466c1.238,3.507,6.198,3.507,7.435,0

3. L304.158,384V8C304.158,3.582,300.576,0,296.158,0z"/>

4. <path style="fill:#FFD788;" d="M255.939,280v232h0.544c1.431-0.119,2.82-0.909,3.393-2.534L304.158,384V280H255.939z"/>

5. <path style="fill:#FFCD00;" d="M296.158,0h-80c-4.418,0-8,3.582-8,8v376c0-8.837,7.164-16,16-16s16,7.163,16,16

6. c0-8.837,7.164-16,16-16s16,7.163,16,16c0-8.837,7.164-16,16-16s16,7.163,16,16V8C304.158,3.582,300.576,0,296.158,0z"/>

7. <path style="fill:#FFCD00;" d="M240.158,384c0-8.837,7.164-16,16-16c8.092,0,14.711,6.028,15.781,13.826V0h-32v381.826

8. C240.037,382.544,240.158,383.255,240.158,384z"/>

9. <path style="fill:#FF9100;" d="M208.158,384c0-8.837,7.164-16,16-16c8.092,0,14.711,6.028,15.781,13.826V0h-24

10. c-4.418,0-8,3.582-8,8v373.826C208.037,382.544,208.158,383.255,208.158,384z"/>

11. <path style="fill:#FFE671;" d="M303.719,384c0-8.837-7.164-16-16-16c-8.092,0-14.711,6.028-15.781,13.826V0h24

12. c4.418,0,8,3.582,8,8v373.826C303.84,382.544,303.719,383.255,303.719,384z"/>

13. <path style="fill:#5C546A;" d="M233.57,456l18.871,53.466c1.238,3.507,6.198,3.507,7.436,0L278.746,456H233.57z"/>

14. <path style="fill:#868491;" d="M255.939,512.031c1.624,0.091,3.288-0.724,3.937-2.565L278.746,456h-22.808L255.939,512.031

15. L255.939,512.031z"/>

16. </svg>

Il a été créé avec huit chemins :

On pourrait composer ce crayon de multiples autres façons avec sans doute une amélioration du code, mais le gain n'en serait finalement pas tellement significatif.

VI - Conclusion

Pour créer une image SVG, il est donc incontournable d'utiliser un éditeur spécialisé comme Inkscape, ou un des multiples proposés en ligne, mais aussi de connaître la syntaxe pour apporter des modifications, nettoyer le code…

VII - Remerciements

Nous tenons à remercier Maurice Chavelli qui nous a autorisés à publier ce tutoriel.

Nous remercions également Winjerome pour la mise au gabarit, et Claude Leloup pour la correction orthographique.