SVG : Scalable Vector Graphics dans une page HTML
LE code des images SVG (Scalable Vector Graphics) est interprété par les navigateurs WEB et peut donc être intégré dans une page HTML. L syntaxe est par contre celle de XML, plus stricte que le HTML. Cette page donne le minimum à connaître pour écrire des images SVG sans passer par un éditeur de telles images.
Une connaissance minimale du HTML est préférable, voyez cette page. La syntaxe du XML, dans laquelle est écrite une image SVG, est plus susceptible que celle du HTML. Par exemple, toute balise ouverte doit être fermée, par exemple toute la description doit se faire entre les balises <svg> et </svg>. Les balises qui ne sont pas englobantes peuvent être auto-fermées par une barre, comme par exemple <line x1="8" y1="5" x2="59" y2="19" />
Page en cours (2025.01), testée avec FireFox 128.6.0esr et Chromium 132.0.6834.83 sur GNU/Linux Debian 12 Bookworm (64 bits)
1. Généralités
1.2 viewBox 2. Éléments simples
2.1 Lignes |
3. path()
3.1 Segments de droite 4. Textes
4.1 Attributs de texte 5. Lien et images |
6. Animations
6.1 set 7. Attributs graphiques
7.1 Utilisez les styles |
1. Généralités
Typiquement, un graphique SVG défini de la sorte produira un rectangle :
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg"> <rect x="75" y="20" width="80" height="40" stroke="cyan" stroke-width="3" fill="yellow" /> </svg>
- La première ligne réserve un espace de 200 pixels de large et de 100 de haut, avec un bord gris d’un pixel d’épaisseur
- La deuxième ligne dessine un rectangle dont le coin supérieur gauche est situé à 75 pixels du bord gauche et à 20 pixels du haut, et de dimension de 80×40 pixels. Il sera jaune, le bord de 3 pixels de large étant cyan
Notes :
- cette page contient dans ses styles la ligne svg { border:1px solid #777 }
- pour créer un fichier SVG indépendant d’une page HTML, voyez Fichier-image.
1.2 L’importance de l’attribut viewBox
Les attributs des balises SVG contiennent souvent des nombres, qui représentent a priori les coordonnées en pixels. Voici un exemple :
<svg width="200" height="100"> <rect x="10" y="20" width="40" height="30" /> </svg>
Mais comme les graphiques doivent pouvoir s’afficher à n’importe quelle échelle («scalable»), il existe un attribut permettant d’agrandir ou diminuer le contenu d’un graphique SVG. viewBox="0 0 400 200" oblige SVG à considérer l’espace réservé de 200×100 comme deux fois plus grand. L’affichage de ses éléments est de ce fait diminué de moitié :x="10" y="20" width="40" height="30"
<svg width="200" height="100" viewBox="0 0 400 200"> <rect x="10" y="20" width="40" height="30" /> </svg>
Avec viewBox="0 0 100 50", l’espace réservé par SVG sera considéré comme diminué de moitié et les dimensions du rectangles seront doublées :
<svg width="200" height="100" viewBox="0 0 100 50"> <rect x="10" y="20" width="40" height="30" /> </svg>
Ci-dessous, viewBox="10 5 200 100" conserve les proportions du rectangle mais supprime les marges de gauche de 10 pixels et du haut des 5 premiers pixels :
<svg width="200" height="100" viewBox="10 5 200 100"> <rect x="10" y="20" width="40" height="30" /> </svg>
viewBox="8 3 100 50" supprime 8 pixels de la marge de gauche et 3 de la marge du haut du rectangle puis double les proportions du rectangle, en ce compris les marges résiduelles, à savoir respectivmement (10 -8) *2 =4 et (10 -3) *2 =14 :
<svg width="200" height="100" viewBox="8 3 100 50"> <rect x="10" y="20" width="40" height="30" /> </svg>
Note : Si les dimensions de l’image ne sont pas proportionnelles à celles de viewBox, les proportions des éléments sont préservées, sauf en présence de l’attribut preserveAspectRatio="none" de la balise <svg> modifie indépendamment les largeur et hauteur des éléments ; les marges résiduelles seront indépendamment proportionnelles, selon des modalités qu’il me reste à déterminer.
<svg width="200" height="100" viewBox="8 3 100 20"> <rect x="10" y="20" width="40" height="30" /> </svg>
1.3 Structures : <g> et <defs>
Regrouper avec <g>
<g> permet de grouper des éléments pour leur appliquer les mêmes attributs définis dans cette balise :
<svg width="90" height="65" xmlns="http://www.w3.org/2000/svg"> <g fill="cyan" stroke="blue" stroke-width="6"> <rect x="10" y="10" width="70" height="30" /> <circle cx="55" cy="40" r="15" /> </g> </svg>
Notes :
- Il est possible d’emboîter plusieurs balises <g>
- Les attributs graphiques sont explicités au chapitre Attributs graphiques.
Prédéfinir avec <defs>
Ce qui est entre <defs> et </defs> permet de définir des balises et des attributs utilisables à divers endroits dans le fichier. L’exemple qui suit définit une ellipse et un dégradé et utilise la balise <use> pour les rassembler. Pour plus de détails, voir Ellipse et Dégradés.
<svg width="220" height="120" xmlns="http://www.w3.org/2000/svg"> <defs> <ellipse id="ellipse0" cx="100" cy="50" rx="100" ry="50" /> <linearGradient id="degrade" gradientTransform="rotate(90)"> <stop offset="10%" stop-color="#70f" /> <stop offset="50%" stop-color="#37f" /> <stop offset="80%" stop-color="#0c0" /> </linearGradient> </defs> <use x="10" y="10" href="#ellipse0" fill="url(#degrade)" /> </svg>
Notes :
- L’appel à l’ellipse (href="#ellipse0") diffère de l’appel à linearGradient (fill="url(#degrade)")
- Il est possible d’utiliser directement la balise <ellipse> en dehors de <defs> ; <use> n’est alors pas nécessaire :
<ellipse cx="110" cy="60" rx="100" ry="50" fill="url(#degrade)" />
2. Éléments simples
2.1 Lignes
Une ligne simple est définie par les coordonnées de deux points, x1, y1 et x2, y2. Cet élément est sensible aux attributs de couleur et de trait.
<svg width="120px" height="120px"> <line x1="40" y1="15" x2="110" y2="90" style="stroke:purple; stroke-width:6; fill:white" /> </svg>
L’attribut stroke-linecap= permet de définir les fins de ligne :
- "butt" termine la ligne au pixel près quelle que soir l’épaisseur de la ligne
- "square" le dernier pixel est le centre d’un carré de côté égal à la largeur de la ligne (=butt si l’épaisseur est d’un pixel
- "round" le dernier pixel est le centre d’un demi-cercle qui prolonge la ligne
2.2 Rectangle
En dehors des éléments vus plus haut, il est possible d’arrondir les angles d’un rectangle :
- rx= permet de définir le rayon de courbure de l’axe des x (0 par défaut)
- ry= permet de définir le rayon de courbure de l’axe des y (idem)
<svg width="150" height="100" xmlns="http://www.w3.org/2000/svg"> <rect x="15" y="10" width="120" height="80" rx="30" ry="15" /> </svg>
Il est possible de pivoter un rectangle avec transform="rotate()". Pour un parallélogramme, il est possible d’utiliser polygone ou déformer un rectangle avec skewX ou skewY.
2.3 Cercles
Les cercles sont définis par :
- cx="" pour l’abscisse du centre
- cy="" pour l’ordonnée du centre
- r="" pour le rayon
<svg width="100px" height="100px"> <circle cx="50" cy="50" r="44" stroke="#b07" stroke-width="5px" fill="#ff7" /> </svg>
2.4 Ellipse
Les ellipses sont définies comme les cercles, mais avec deux rayons, rx et ry
<svg width="100px" height="100px"> <ellipse cx="50" cy="50" rx="30" ry="44" stroke="#70b" stroke-width="5px" fill="7ff" /> </svg>
Il est possible d’orienter une ellipse avec transform="rotate()" ou en utilisant les arcs d’ellipse de <path>.
2.5 Polygones
Les polygones sont définis par un ensemble de coordonnées de points. L’abscisse et l’ordonnée de chaque point sont reliés par une virgule, ces couples de valeurs sont séparés par une espace. La figure est nécessairement «fermée», c’est-à-dire que le dernier point est relié au premier. Cet élément est sensible aux attributs de couleur et de trait.
<svg width="200px" height="200px"> <polygon points="40,40 160,30 180,140 30,180" style="stroke:blue; stroke-width:2; fill:yellow" /> </svg>
2.6 Polyline
Il s’agit d’un polygone non fermé, qu’il est néanmoins possible de remplir. Les points sont définis leurs abscisse,ordonnée séparées par des espaces. Cet élément est sensible aux attributs de couleur et de trait.
<svg width="200px" height="200px"> <polyline points="20,40 100,100 180,50 160,100 180,160 40,140" style="stroke:darkgreen;stroke-width:4;fill:lime" /> </svg>
3. Path
<path> permet des figures mêlant segments de droites et courbes et utilisant volontiers des coordonnées relatives aux précédentes, et donc des valeurs parfois négatives. Cet élément est sensible à la casse (majuscules ou minuscules), aux attributs de couleur et de trait. Bien qu’une même définition permette différents types de courbes et segments de droite, la description des différents éléments se fait de façon progressive.
3.1 Segments de droites
Path peut servir comme <polyline> ou <polygone> selon que Z ferme ou non la définition, mais permet plus de souplesse dans le tracé et dans sa description : saut, trait horizontal ou vertical, mais surtout coordonnées absolues ou relatives.
<svg width="200px" height="150px"> <path d="m 10 20 l 70 70 L 110 50 h 50 v 80 h -70 l 25 -25 m 0 15 l 30 -25" style="stroke:darkgreen;stroke-width:4;fill:lime" /> </svg>
Les lettres majuscules indiquent des coordonnées absolues, les minuscules des coordonnées relatives, qui peuvent être négatives.
- M = saute à une coordonnée sans rien tracer ; commence un chemin
- L = crée une ligne de la coordonnée actuelle à la coordonnée qui suit ; l si relative
- H = trace une ligne horizontale jusqu’à l’abscisse précisée ; h pour une abscisse relative
- V = trace une ligne verticale jusqu’à l’ordonnée précisée ; v pour une ordonnée relative
- Z «ferme» la figure en reliant le dernier point au premier. Ce n’est effectif que si le chemin n’est pas interrompu par un M ou m
Note : Les lettres peuvent être collées aux nombres. M 20 20 h 50 peut s’écrire M20 20h50.
3.2 Courbes cubiques
Les courbes de Bézier permettent un chemin flexible. La commande C code une courbe entre deux points avec deux points de contrôle. Plus la distance entre ces derniers est grande, plus la courbe est refermée. Une plus grande longueur entre un point de bout de courbe et son point de contrôle (segments rouges) creuse davantage la courbe (voir commande S).
La formule doit d’abord définir un point de départ (x0 y0), comporter un C, puis les coordonnées du point de contrôle du point de départ (cx0 cy0) et du point de contrôle du point d’arrivée (cx1 cy1) et enfin le point d’arrivée (x1 y1) : M x0 x0 C cx0 cy0, cx1 cy1, x1 y1
Les graphiques ci-dessous indiquent en rouge les points et tangentes qui explicitent la construction de la courbe. Ils ont dû être expressément ajoutés mais ne sont pas repris dans le code XML ci-dessous :
<svg width="640" height="140"> <path d="M 20 20 C 40 80, 100 120, 120 20" style="stroke:black;stroke-width:2;fill:none" /> <path d="M 160 20 C 160 80, 260 120, 260 20" style="stroke:black;stroke-width:2;fill:none" /> <path d="M 310 20 C 290 80, 430 120, 410 20" style="stroke:black;stroke-width:2;fill:none" /> <path d="M 500 20 C 440 80, 620 120, 580 20" style="stroke:black;stroke-width:2;fill:none" /> </svg>
La courbe S n’a qu’un point de contrôle. Le graphique ci-dessous montre comment l’éloignement accentue la profondeur de la courbure.
<svg width="500" height="140"> <circle cx="100" cy="50" r="2.5" fill="#b04" /> <circle cx="220" cy="70" r="2.5" fill="#b04" /> <circle cx="340" cy="90" r="2.5" fill="#b04" /> <circle cx="460" cy="110" r="2.5" fill="#b04" /> </svg>
La commande S sert surtout à suivre une commande C pour relier plus de deux points. Cela donne parfois des résultats plus complexe comme l’addition des deux premières courbes donnant la troisième. En effet, un point de contrôle est automatiquement créé à l’opposé du second de la courbe C par rapport au point d’inflexion (en bleu). On voit que c’est ce qui se passe si on trace la courbe avec une commande C (quatrième courbe).
<svg width="850" height="240"> <path d="M 40 80 C 40 140, 120 140, 140 80" style="stroke:black;stroke-width:2;fill:none" /> <path d="M 170 80 S 250 110, 270 80" style="stroke:black;stroke-width:2;fill:none" /> <path d="M 320 80 C 320 140, 400 140, 420 80 S 500 110, 520 80" style="stroke:black;stroke-width:2;fill:none" /> <path d="M 560 80 C 580 20, 640 110, 660 80" style="stroke:black;stroke-width:2;fill:none" /> </svg>
Un enchaînement de courbe «cubique» commence par poser un point avec M, utilise une commande C avec deux points de contrôle suivis du point terminant le premier segment ; par la suite, c’est la commande S qui est utilisée, chaque fois en ajoutant un point de contrôle et un point d’arrivée.
3.3 Courbes quadratiques
La commande Q dessine un segment de courbe à un seul point de contrôle.
<svg width="140" height="100"> <path d="M 20 20 Q 80 80, 120 20" style="stroke:black;stroke-width:2;fill:none" /> </svg>
Les commandes S et Q donnent des courbes assez proches, néanmoins :
<svg width="200px" height="200px"> <path d="M 40 50 Q 120 180, 160 50" style="stroke:blue;stroke-width:3;fill:none;stroke-opacity:1" /> <path d="M 40 50 S 120 180, 160 50" style="stroke:green;stroke-width:3;fill:none;stroke-opacity:0.5" /> </svg>
Note : comme pour le graphique précédent, le point de contrôle et les segments tangents ont été ajoutés mais ne figurent pas sur le code expliqué.
La commande T n’est utilisée qu’en suite de Q, son point de contrôle est automatiquement calculé (petit cercle évidé) selon la position du précédent (de la même manière que le premier point de contrôle de S est calculé selon le second de C) :
<svg width="470" height="170"> <path d="M 150 80 Q 210 140, 230 80 T 350 60 T 370 130" style="stroke:black;stroke-width:2;fill:none" /> <path d="M 350 80 Q 360 140, 430 80 T 550 60 T 570 130" style="stroke:black;stroke-width:2;fill:none" /> </svg>
Les points de coordonnées sont identiques pour les deux courbes (abscisses +200 pour le second graphique). Seul l’unique point de contrôle (path avec Q, abscisse +150 seulement) est modifié, tous les autres sont recalculés, ce qui modifie toute la courbe.
3.4 Arcs d’ellipse orientable
M x1 x2 A da1 da2 ang lf sf x2 y2 dessine un arc défini par deux points d’une ellipse, la longueur des axes et l’orientation du premier des deux :
- x1 y1 et x2 y2 sont les deux points de l’ellipse qui bornent l’arc
- da1 et da2 sont les longueurs des demi-axes
- ang est l’angle, en degrés sens horaire, de l’orientation du premier axe
- lf et sf (0 ou 1) sont deux drapeaux dont la combinaison permet de tracer les quatre arcs d’ellipse possibles
- lf pour large-arc-flag ; 1 choisit le plus grand des deux arcs possibles
- sf pour sweep-flag ; 1 pour la courbe empruntant le sens horaire à partir du point de départ
Note : pour un cercle, les deux demi-axes doivent être égaux et équivalent au rayon ; l’orientation n’a alors aucune incidence.
<svg width="500px" height="240px"> <g style="stroke-width:2;fill:none"> <path d="M 80 120 A 40 80 -50 1 1 140 70" style="stroke:#00C" /><!-- bleu --> <path d="M 80 120 A 40 80 -50 0 0 140 70" style="stroke:#0A0" /><!-- vert --> <path d="M 80 120 A 40 80 -50 0 1 140 70" style="stroke:#B0B" /><!-- mauve --> <path d="M 80 120 A 40 80 -50 1 0 140 70" style="stroke:#D00" /><!-- rouge --> </g> <circle cx="80" cy="120" r="3" fill="#000" /> <circle cx="140" cy="70" r="3" fill="#000" /> </svg>
Note : non visibles dans le code, les points p1 et p2 ainsi que les valeurs des drapeaux ont été ajoutés pour chaque arc d’ellipse. À droite, les ellipses sont produites avec les mêmes définitions (à une translation près) mais avec orientation du premier axe de +50 (degrés).
4. Textes
<svg width="200px" height="140px"> <text x="20" y="50" stroke="black" stroke-width="2" fill="none" font-size="48">H-W</text> <text x="10" y="90" stroke="gray" font-size="24">Bonjour, monde!</text> <a href="http://jchr.be/" target="_blank"><text x="100" y="120" fill="#b04">jchr.be</text></a> </svg>
Note : il semble que le texte inclus ne peut comporter de balise.
4.1 Attributs de textes
Alignement horizontal avec text-anchor=""
- "start" pour un alignement à partir de l’abscisse de <text>
- "middle" pour centrer le texte sur l’abscisse de <text>
- "end" pour la fin du texte à l’abscisse précisée de <text>
<svg width="400" height="400"> <line x1="60" y1="5" x2="60" y2="100" stroke="red" stroke-dasharray="2 2 5 2" /> <text text-anchor="start" x="60" y="30">SVG</text> <text text-anchor="middle" x="60" y="60">SVG</text> <text text-anchor="end" x="60" y="90">SVG</text> </svg>
Alignement vertical avec dominant-baseline=""
- "text-top" au-dessus de la ligne
- "middle" de part et d’autre de la ligne
- "mathematical" haut de l’œil collé à la ligne
- "hanging" haut du corps collé à la ligne
<svg width="430" height="400"> <line x1="10" y1="30" x2="420" y2="30" stroke="red" stroke-dasharray="3 3 7 3" /> <text dominant-baseline="text-top" x="20" y="30">text-top</text> <text dominant-baseline="middle" x="110" y="30">middle</text> <text dominant-baseline="mathematical" x="190" y="30">mathematical</text> <text dominant-baseline="hanging" x="330" y="30>hanging</text> </svg>
4.2 textPath
Pour qu’un texte suive une courbe définie par path :
<svg width="300px" height="240px"> <path id="cosh" d="M 20 30 q 150 250, 250 0" stroke="transparent" fill="none" /> <text style="fill:blue;font-size:32px"> <textPath href="#cosh" startOffset="50">Bonjour, le monde!</textPath> </text> </svg>
- on définit un <path> que l’on identifie avec id="xxx"
- <textPath> doit comporter la référence href="#xxx"
- <textPath> contient le texte à afficher et doit être entouré de <text></text>
- startOffset="" permet d’ajuster le texte par rapport à la courbe
5. Liens et fichiers image
5.1 Lien cliquable>
Tout élément inclus entre <a href=""> et </a> peut servir de lien à cliquer. Dans l’exemple suivant, le disque bleu pointe vers le moteur de recherche duckduckgo.com, «jchr.be» vers le site qui héberge la présente page.
<svg width="200px" height="135px"> <a href="http://duckduckgo.com/" target="_blank"><circle cx="60" cy="55" r="40" fill="#40b" /></a> <a href="http://jchr.be/" target="_self"><text x="100" y="115" fill="#b04">jchr.be</text></a> </svg>
- href="" pour encoder l’URL de la page
- hreflang="" definit la langue de la page
- target="" choisit l’onglet dans lequel ouvrir le lien :
- _self charge la cible sur l’onglet actuel
- _blank charge la cible sur un nouvel onglet
- des noms au choix, différents pour des onglets séparés
- _parent et _top concernent les <iframe>
- type="" précise le type MIME de la cible
- download ?permet un téléchargement plutôt que l’ouverture du lien
5.2 Fichier-image
Un fichier d’image SVG doit commencer par <?xml version="1.0" encoding="utf-8"?> et la balise <svg> doit pour bien faire contenir xmlns="http://www.w3.org/2000/svg". Le logiciel libre Inkscape produit ce genre de fichiers, qui sont lus par le logiciel libre Image-Magick et les afficheurs d’images des bureaux GNU/Linux (Plasma, Gnome, Mate-desktop…).
Exemple de fichier d’image SVG sauvegardé sous le nom svg.svg :
<?xml version="1.0" encoding="utf-8"?> <svg width="180" height="50" xmlns="http://www.w3.org/2000/svg" style="background:#fea"> <text x="10" y="30" stroke="black" font-size="18">Bonjour, monde!</text> </svg>
Notes :
- xmlns="http://www.w3.org/2000/svg" n’est pas nécessaire pour les logiciels Inkscape, ImageMagick ou les afficheurs des différents Bureaux de GNU/Linux ; FireFox et Chromium par contre l’exigent pour pouvoir l’afficher en tant que fichier ; Chromium accepte une image dans les balises <object> et <iframe>, mais sans les styles ; FireFox l’accepte dans <iframe> (avec les styles) dans mais pas dans <object>. Moralité : prévoyez toujours cet attribut pour les fichiers-images.
- il existe des fichiers compressés SVGZ, mais ils sont déconseillés du fait d’être rarement reconnus.
5.3 Afficher un fichier SVG
Les balises <object> et <iframe> permettent d’afficher le fichier svg.svg dans une page HTML :
<object data="svg-sans.svg" type="image/svg+xml"></object>
<iframe src="svg-sans.svg"></iframe>
La balise <image> permet d’inclure un fichier SVG (PNG ou JPG) dans une image SVG :
- href="" l’URL de l’image
- x="" l’abcisse du coin supérieur gauche de l’image
- y="" l’ordonnée du coin supérieur gauche de l’image
- width="" largeur de l’image
- height="" la hauteur de l’image
<svg width="300px" height="220px" viewBox="0 0 100 100"> <text x="0" y="20" style="font-size:12px">L’image svg.svg :</text> <image href="svg.svg" x="0" y="30" width="100" height="50" /> </svg>
6. Animations
6.1 <set>
<set> permet de changer un attribut après un délai, défini avec begin="_s" ; plusieurs changements liés à des délais différents peuvent être définis ; l’ordre «chronologique» des changements ne doit pas être respecté dans les définitions.
<svg width="220" height="150" xmlns="http://www.w3.org/2000/svg"> <rect x="10" y="10" width="100" height="100" stroke="black" stroke-width="5" fill="none"> <set attributeName="width" to="200" begin="2s" /> <set attributeName="y" to="20" begin="4s" /> <set attributeName="stroke" to="red" begin="6s" /> <set attributeName="stroke-width" to="2" begin="8s" /> <set attributeName="fill" to="blue" begin="10s" /> </rect> <svg>
Pour bien assigner les changements à un élément particulier, on ne le ferme pas tout de suite avec /> mais après les <set>, explicitement avec le nom de l’élément. Il est également possible d’assigner les <set> avec href="#xxx" à un élément identifié avec id="xxx" :
<svg width="220" height="150"> <rect id="r1" x="10" y="10" width="100" height="100" stroke="black" stroke-width="2" fill="none" /> <set href="#r1" attributeName="width" to="200" begin="10s" /> <set href="#r1" attributeName="y" to="30" begin="6s" /> <set href="#r1" attributeName="stroke" to="red" begin="2s" /> <set href="#r1" attributeName="stroke-width" to="5" begin="8s" /> <set href="#r1" attributeName="fill" to="blue" begin="4s" /> </svg>
6.2 <animate>
<svg width="160" height="100"> <ellipse cx="5" cy="3" rx="5" ry="3" fill="#b05"> <animate attributeName="cx" begin="0s" dur=".5s" from="3" to="295" repeatCount="41" /> <animate attributeName="cy" begin="0s" dur="20s" from="2" to="95" fill="freeze" /> </ellipse> </svg>
En lieu et place de repeatCount="indefinite", il est possible d’utiliser fill="freeze" pour stopper l’animation en fin de course
<svg width="100" height="100"> <ellipse cx="50" cy="50" rx="40" ry="30" fill="#b04"> <animate attributeName="rx" by="-20" dur="3s" fill="freeze" /> </ellipse> </svg>
by="" permet de modifier graduellement un attribut d’élément graphique
fill="freeze" gèle l’animation en fin de parcours ; repeatCount="1" revient au point de départ.
6.3 <animateMotion>
<animateMotion> permet une animation le long d’un path, dessiné pour bien visualiser le trajet.
<svg width="350" height="120"> <g> <ellipse cx="-25" cy="0" rx="50" ry="10" stroke="red" fill="none" /> <text x="-50" y="6" style="font-family:sans;font-size:14">LOOP!</text> <animateMotion path="M 50 60 Q 100 0, 150 60 T 250 60 T 350 60 Q 300 120, 250 60 T 150 60 T 50 60" begin="0s" dur="10s" repeatCount="indefinite" /> </g> <path d="M 25 60 Q 75 0, 125 60 T 225 60 T 325 60 Q 275 120, 225 60 T 125 60 T 25 60" stroke-width="1" stroke="#777" fill="none"> </svg>
6.4 <animatetransform>
<svg width="200" height="200"> <ellipse cx="100" cy="25" rx="10" ry="20" style="stroke:red;stroke-width:3;fill:yellow"> <animateTransform attributeName="transform" begin="0s" dur="3s" type="rotate" from="0 100 100" to="360 100 100" repeatCount="indefinite" /> </ellipse> <ellipse cx="100" cy="75" rx="7" ry="15" style="stroke:blue;stroke-width:3;fill:green"> <animateTransform attributeName="transform" begin="0s" dur="36s" type="rotate" from="0 100 100" to="360 100 100" repeatCount="indefinite" /> </ellipse> </svg>
from="60 x y" définit l’angle de départ, l’abscisse et l’ordonnée du point fixe de la rotation ; pareil pour to=""
type="translate" prend pour valeurs les coordonnées des points de passage :
<svg width="200" height="200""> <ellipse cx=100 cy="100" rx="30" ry="65" fill="#79e"> <animateTransform attributeType="xml" attributeName="transform" values="-20,-20 ; 20,-20 ; -20,20 ; 20,20 ; -20,-20" type="translate" dur="3s" repeatCount="indefinite" /> </ellipse> </svg>
type="scale" prend pour valeurs les différentes échelles par lesquelles passer :
<svg width="200" height="200" viewBox="-60, -60, 120, 120"> <ellipse cx=0 cy="0" rx="40" ry="20" fill="#b04"> <animateTransform attributeType="xml" attributeName="transform" values="0.9; 1.15; 1; 1.3; 0.9" type="scale" dur="5s" repeatCount="indefinite"> </ellipse> </svg>
Composer deux animateTransform demande l’attribut additive="sum" sur le second :
<svg width="200" height="200" viewBox="-100 -100 200 200"> <circle cx=0 cy="0" r="50" fill="#fd0"> <animateTransform attributeType="xml" attributeName="transform" values="-20,-20 ; 20,-20 ; -20,20 ; 20,20 ; -20,-20" type="translate" dur="3s" repeatCount="indefinite" /> <animateTransform attributeType="xml" attributeName="transform" values="1;1.2;1;1.4;1" type="scale" dur="5s" repeatCount="indefinite" additive="sum" /> </circle> </svg>
7. Attributs graphiques
Il peut être judicieux d’insérer les attributs graphiques dans un attribut style="" ou dans des classes, définies entre les balises <style> et </style> de début de page HTML.
7.1 Utilisez les styles
La bonne intégration du SVG dans le HTML permet que des attributs contenus dans la balise puissent être regroupés dans un attribut style="" :
<rect x="75" y="20" width="80" height="40" style="stroke:cyan; stroke-width:3; fill:yellow" />
…ou encore faire l’objet d’une classe définie entre les balises <style> et </style> de début de page HTML.
<html><head> <style> .ua { stroke:cyan; stroke-width:3; fill:yellow; } </style> </head><body> <svg width="300" height="200" xmlns="http://www.w3.org/2000/svg"> <rect class="ua" x="75" y="20" width="80" height="40" /> </svg> </body></html>
7.2 Couleurs et opacité
stroke="" définit la couleur du trait qui entoure une forme géométrique
fill="" définit la couleur du remplissage de l’intérieur d’une figure, ou de l’épaisseur du trait (text)
La définition d’une couleur peut se faire :
- à l’aide de noms de couleurs agréées (black, white, red, dark-red, orange, yellow, green, dark-green, lime, cyan, blue, purple… voir cette page)
- par la formule rgb(24 56 156), ou les trois nombres vont de 0 à 255 ; possible avec des pourcentages : rgb(25% 50% 90%)
- par les valeurs hexadécimales des composantes rouges, vertes et bleues à un chiffre (de 0 à 9 et de A à F) ou à deux chiffres (00 à FF), comme par exemple "#b04" ou "#b70948", voir cette page
- par la formule hsl(60 56% 65%), le premier nombre définissant l’angle dans la roue des couleurs, le deuxième la saturation et le troisième la luminosité :
- 0 pour le rouge, 60 pour le jaune, 120 pour le vert, 180 pour le cyan, 240 pour le bleu, 300 pour le mauve, avec tous les intermédiaires
- 100% pour la couleur la plus intense (les disques les plus grands) ; 0% pour le gris
- 50% pour la couleur la plus nette, assombrissement (30% pour la rosace intérieure) vers 0% (noir), éclaircissement (70% pour la rosace extérieure) vers 100% (blanc)
stroke-opacity="" détermine l’opacité du trait-contour
fill-opacity="" détermine l’opacité de la couleur du corps de la figure
L’opacité va de 0.0 ou transparent à opaque 1.0 (par défaut). Il est possible de la préciser avec un pourcentage dans les formules rgb(24 56 200 / 40%) et hsl(60 80% 60% / 40%)
<svg width="120", height="120"> <rect x="10" y="20" width="100", height="40" fill="#f77" /> <rect x="20" y="10" width="40", height="100" fill="rgb(0 255 255 / 50%)" /> </svg>
Dégradés de couleurs
Il existe deux formes de dégradés : le gradient linéaire et le radial.
linearGradient définit les couleurs et leur proportionnalité selon un sens. l’id="" permet un appel à cette définition de la balise de l’élément coloré
<svg width="150" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg"> <defs> <linearGradient id="rasta" x1="0" y1="0" x2="1" y2="0"> <stop offset="0%" stop-color="darkgreen" /> <stop offset="50%" stop-color="yellow" /> <stop offset="100%" stop-color="red" /> </linearGradient> </defs> <rect x="0" y="0" width="150" height="100" fill="url(#rasta)" /> </svg>
Il est possible d’inverser le sens du dégradé en intervertissant les valeurs de x1 et x2, ou de changer de direction en intervertissant les valeurs des x et des y, voire faire un dégradé oblique en utilisant gradientTransform="rotate()"
radialGradient permet un dégradé du centre vers l’extérieur.
<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg"> <defs> <radialGradient id="cocarde"> <stop offset="0%" stop-color="#0f0" /> <stop offset="70%" stop-color="#0bb" /> <stop offset="100%" stop-color="#d0f" /> </radialGradient> </defs> <circle cx="50" cy="50" r="50" fill="url(#cocarde)" /> </svg>
Il est possible de décentrer la cocarde de couleur, par exemple avec
<radialGradient id="cocarde" cx="0.6" cy="0.4" r="0.6">
spreadMethod="" définit le comportement lors du dépassement de la définition :
- "pad" (par défaut), la dernière couleur définie continue
- "repeat" poursuit en reprenant le même motif
- "reflect" poursuit dans le sens inverse
+ gradientUnits="objectBoundingBox" ou userSpaceOnUse
7.3 Attributs de trait
Largeur de trait
stroke-width="" détermine l’épaisseur du trait-contour de la figure (1 par défaut). Attention : c’est le centre du trait qui satisfait aux grandeurs indiquées.
Discontinuité
L’attribut stroke-dasharray="" définit un mode de discontinuité, défini par une succession de nombres précisant successivement la couleur et la transparence ; en cas de nombre impair de nombres, la succession s’inverse. Pour "12 6 2" :
xxxxxxxxxx······xx··········xxxxxx·· etc.
<svg width="200px" height="200px"> <polyline points="20,40 100,100 180,50 160,100 180,160 40,140" stroke-dasharray="10 6 2" stroke-width="4" fill="darkgreen" /> </svg>
Notes : des pourcentages sont possibles, stroke-dasharray="6% 2%"
Décorations de ligne
L’attribut stroke-linecap="" définit les fins de ligne, une fine ligne blanche étant ajoutée pour mieux visualiser les effets de fin de ligne :
<svg width="160px" height="120px"> <line x1="30" y1 ="30" x2="30" y2="90" stroke-width="20" stroke-linecap="square" stroke="purple" fill="tranparent" /> <line x1="55" y1 ="30" x2="55" y2="90" stroke-width="1" stroke="black" /> <line x1="80" y1 ="30" x2="80" y2="90" stroke-width="20" stroke-linecap="butt" stroke="purple" /> <line x1="105" y1 ="30" x2="105" y2="90" stroke-width="1" stroke="black" /> <line x1="130" y1 ="30" x2="130" y2="90" stroke-width="20" stroke-linecap="round" stroke="purple" /> </svg>
- stroke-linecap="square" le dernier pixel est le centre d’un carré de côté égal à la largeur de la ligne (="butt" si l’épaisseur est d’un pixel)
- stroke-linecap="butt" (par défaut) termine la ligne au pixel près quelle que soit l’épaisseur de la ligne
- stroke-linecap="round" le dernier pixel est le centre d’un demi-cercle qui prolonge la ligne
L’attribut stroke-linejoin="" définit les jointures d’angle d’une ligne brisée :
<svg width="300px" height="160px"> <polyline points="30,20 70,60 30,100 70,140" stroke-width="20" stroke-linejoin="miter" stroke="blue" fill="none" /> <polyline points="130,20 170,60 130,100 170,140" stroke-width="20" stroke-linejoin="bevel" stroke="blue" fill="none" /> <polyline points="230,20 270,60 230,100 270,140" stroke-width="20" stroke-linejoin="round" stroke="blue" fill="none" /> </svg>
- stroke-linejoin="miter" dessine l’angle jusqu’au bout
- stroke-linejoin="bevel" coupe l’angle
- stroke-linejoin="round" arrondit l’angle
Et encore…
fill-rule, stroke-miterlimit, stroke-dashoffset
offset, offset-path, offset-anchor, offset-distance, offset-path, offset-position, offset-rotate
7.4 Transformations
L’attribut transform="" permet d’appliquer des modifications à un élément ou à un ensemble d’éléments regroupés avec <g></g>. Il est possible d’enchaîner deux ou plusieurs transformations au même élément en les séparant d’une espace :
transform="scale(10,20) rotate(45)"
Translation
"translate(,)" déplace un élément sans devoir modifier tous ses attributs de coordonnées.
<svg width="100" height="100"> <circle cx="60" cy="0" r="40" fill="#777" /> <circle cx="60" cy="0" r="40" transform="translate(-20,20)" fill="green" fill-opacity="0.5" /> </svg>
Rotations
rotate() opère une rotation de l’élément, le premier paramètre est l’angle de rotation (horaire), transform-origin="dx dy" définit le point fixe de la rotation, mais il semble que transform="rotate(30 dx dy)" peut également faire l’affaire.
Attention : Lors d’une composition de transformations, la seconde tient compte du changement de coordonnées de la première. Dans l’exemple ci-dessous, la translation «horizontale» devient de ce fait oblique (avec le rectangle bleu comme résultat intermédiaire) :
scale() permet de diminuer ou agrandir un élément ; il est possible de prévoir deux rapports différents pour les dimensions. transform-origin="" détermine le point fixe de la transformation.
skewX() et skewY() provoquent un cisaillement horizontal (rose) et vertical (vert) ; il est possible de préciser le point fixe de la transformation avec transform-origin="x y".
<svg width="100" height="100">
<ellipse cx="50" cy="50" rx="28" ry="40" fill="#444" />
<ellipse cx="50" cy="50" rx="28" ry="40" transform="rotate(50)" transform-origin="50 50" fill="green" fill-opacity="0.5" />
</svg>
<svg width="100" height="100">
<rect x="10" y="20" width="40" height="20" fill="#777" />
<rect x="10" y="20" width="40" height="20" transform="rotate(30)" transform-origin="30 30" fill="blue" fill-opacity="0.5" />
<rect x="10" y="20" width="40" height="20" transform="rotate(30) translate(45,0)" transform-origin="30 30" fill="green" fill-opacity="0.5" />
</svg>
Échelle
<svg width="100" height="100">
<rect x="10" y="20" width="40" height="30" fill="#777" />
<rect x="10" y="20" width="40" height="30" transform="scale(1.8)" fill="red" fill-opacity="0.5" />
<rect x="10" y="20" width="40" height="30" transform="scale(0.7,3)" fill="green" fill-opacity="0.5" transform-origin="10 10" />
</svg>
Cisaillements
<svg width="100" height="100">
<rect x="10" y="20" width="40" height="30" fill="#777" />
<rect x="10" y="20" width="40" height="30" transform="skewX(30)" fill="red" fill-opacity="0.5" transform-origin="30 20" />
<rect x="10" y="20" width="40" height="30" transform="skewY(45)" fill="green" fill-opacity="0.5" />
</svg>