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) :

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 :
2.
<line
x1
=
"20"
y1
=
"50"
x2
=
"100"
y2
=
"50"
style
=
"stroke: blue; stroke-width: 25;"
/>
<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 :

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 :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
<svg height
=
"400"
width
=
"400"
>
<style>
line {
stroke:
purple
;
stroke-width:
20
;
}
</style>
<line x1
=
"20"
y1
=
"20"
x2
=
"140"
y2
=
"20"
stroke-linecap
=
"butt"
/>
<line x1
=
"20"
y1
=
"50"
x2
=
"140"
y2
=
"50"
stroke-linecap
=
"round"
/>
<line x1
=
"20"
y1
=
"80"
x2
=
"140"
y2
=
"80"
stroke-linecap
=
"square"
/>
</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 :
2.
3.
4.
5.
6.
7.
8.
9.
10.
<svg
height
=
"400"
width
=
"400"
>
<style>
polyline {
stroke: green;
stroke-width: 10;
stroke-linecap: round;
stroke-linejoin: round;
fill: none; }
</style>
<polyline
points
=
"60 140, 100 50, 55 100, 55 10, 25 100"
/>
</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 :
2.
3.
4.
5.
6.
<svg
height
=
"400"
width
=
"400"
>
<rect
x
=
"20"
y
=
"20"
width
=
"50"
height
=
"90"
style
=
"fill-opacity: 0.3"
/>
<rect
x
=
"40"
y
=
"10"
width
=
"80"
height
=
"40"
style
=
"fill: none; stroke: black;"
/>
<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"
/>
<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"
/>
</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 :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
<?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"
id
=
"svg8"
version
=
"1.1"
viewBox
=
"0 0 159 106"
height
=
"400"
width
=
"600"
>
<defs
id
=
"defs2"
/>
<metadata
id
=
"metadata5"
>
<
rdf
:
RDF>
<
cc
:
Work
rdf
:
about
=
""
>
<
dc
:
format>
image/svg+xml</
dc
:
format>
<
dc
:
type
rdf
:
resource
=
"http://purl.org/dc/dcmitype/StillImage"
/>
<
dc
:
title></
dc
:
title>
</
cc
:
Work>
</
rdf
:
RDF>
</metadata>
<g
transform
=
"translate(0,-191)"
id
=
"layer1"
>
<path
id
=
"path836"
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"
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"
/>
</g>
</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 :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns
=
"http://www.w3.org/2000/svg"
>
<path
d
=
"M432,8H80C66.766,8,56,18.766,56,32v456c0,13.234,10.766,24,24,24h352c13.234,0,24-10.766,24-24V32
C456,18.766,445.234,8,432,8z"
style
=
"fill:#FF4F19;"
/>
<path
d
=
"M95.781,8H80C66.766,8,56,18.766,56,32v456c0,13.234,10.766,24,24,24h15.781V8z"
style
=
"fill:#E3001E;"
/>
<path
d
=
"M400,0h-80c-4.418,0-8,3.582-8,8v119.996c0,2.883,1.547,5.543,4.055,6.961
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
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"
style
=
"fill:#5D647F;"
/>
<path
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"
style
=
"fill:#C10019;"
/>
<path
d
=
"M355.781,344h-0.572c-0.071-0.272-0.084-0.545-0.17-0.816L309.76,199.801
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
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
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
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
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"
style
=
"fill:#FFCD00;"
/>
</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 :
2.
3.
4.
5.
6.
7.
8.
9.
<rect
style
=
"fill:#ff4f19;"
id
=
"rect28"
width
=
"396"
height
=
"506"
x
=
"55"
y
=
"8"
ry
=
"25.1"
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é :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<svg
version
=
"1.1"
xmlns
=
"http://www.w3.org/2000/svg"
viewBox
=
"0 0 512.096 512.096"
>
<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
L304.158,384V8C304.158,3.582,300.576,0,296.158,0z"
/>
<path
style
=
"fill:#FFD788;"
d
=
"M255.939,280v232h0.544c1.431-0.119,2.82-0.909,3.393-2.534L304.158,384V280H255.939z"
/>
<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
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"
/>
<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
C240.037,382.544,240.158,383.255,240.158,384z"
/>
<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
c-4.418,0-8,3.582-8,8v373.826C208.037,382.544,208.158,383.255,208.158,384z"
/>
<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
c4.418,0,8,3.582,8,8v373.826C303.84,382.544,303.719,383.255,303.719,384z"
/>
<path
style
=
"fill:#5C546A;"
d
=
"M233.57,456l18.871,53.466c1.238,3.507,6.198,3.507,7.436,0L278.746,456H233.57z"
/>
<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
L255.939,512.031z"
/>
</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.