title: SVG, le dessin vectoriel pour le web
url: http://www.alsacreations.com/tuto/lire/1421-svg-initiation-syntaxe-outils.html
hash_url: 5a64a81a55
SVG est un format d'images vectorielles basé sur le langage de balisage XML. Il répond parfaitement à des besoins graphiques légers, qu'ils soient statiques, dynamiques ou interactifs.
SVG (Scalable Vector Graphics) est un format de dessin vectoriel, élaboré à partir de 1998 par un groupe de travail comprenant entre autre IBM, Apple, Microsoft, Xerox.
Il a mis du temps à être estimé à sa juste valeur sur le Web, notamment à cause de sa lente adoption par les navigateurs. En effet, Internet Explorer ne l'a pris en charge qu'a partir de sa version 9. Il était possible, au moyen d'extensions propriétaires, de parvenir à un rendu similaire mais leur installation était contraignante et paradoxale vis-à-vis de ce format ouvert. Pour ce qui est des autres acteurs majeurs, SVG dans sa version 1.1 est reconnu et interprété, à partir de Firefox 4+, Chrome 16+, Safari 5+ et Opera 9.5+ (voir détail des moteurs de rendu sur Wikipedia).
SVG est un format d'image léger lorsqu'il s'agit de représenter des formes simples, car seules les informations décrivant ces formes sont stockées (coordonnées, couleurs, effets) contrairement aux images bitmap (JPG, PNG, GIF) qui doivent mémoriser le contenu pixel par pixel. Ce principe rend les images SVG étirables sans perte de qualité. Il est également une alternative à Flash pour les petites animations lorsqu'il est combiné à SMIL, ou pour présenter des données qui doivent être dynamiques.
SVG est dans la lignée de HTML : spécifié par le W3C, ouvert, libre, simple d'utilisation. Il interagit avec les différents langages qui composent nos pages web.
En tant que format vectoriel, SVG est éditable dans un logiciel tel qu'Illustrator ou Inkscape, pour ne citer que les deux plus célèbres protagonistes, ce qui rend triviale la création de formes complexes. Il existe d'autres outils pour manipuler ce format.
Exemple de dessin dans Inkscape
(sans écrire une seule ligne de code)
Il y a différentes possibilités plus ou moins pratiques et plus ou moins supportées, afin d'intégrer du SVG dans une page web.
<embed>
Cet élément non standard a été créé pour combler un manque du côté des spécifications du W3C. Employé en des temps obscurs, nous éviterons donc son utilisation.
<object>
Introduite en HTML4 la balise fourre-tout <object>
peut également être utilisée pour importer du contenu SVG dans une page web.
<object type="image/svg+xml" data="kiwi.svg" width="200" height="100">
Le navigateur ne peut lire ce kiwi
</object>
<svg>
HTML5 introduit un nouvel élément afin d'embarquer du contenu SVG dans une page web. L'élément <svg>
permet de ne plus ce soucier du namespace et d'intérargir avec les nœuds de SVG directement au sein du document HTML.
<svg width="200" height="100">
...
</svg>
<img>
Même s'il est possible d'inclure du SVG dans la balise <img>
, c'est à éviter dans la mesure où cette balise n'a pas été faite pour accueillir des éventuels comportements scriptés. À partir du moment où vous utilisez Javascript avec SVG, il vaudra mieux éviter de l'inclure via la balise <img>
, pour une utilisation plus basique cette balise sera totalement appropriée. À noter que cette partie de la spécifications est toujours en brouillon.
<img src="kiwi.svg" alt="Un kiwi en SVG">
Fonctionnant en synergie avec SVG, ont peut également inclure ce format comme ressource pour un background CSS. De plus, quand vous utilisez @font-face
vous êtes également susceptible d'employer des fontes SVG.
.kiwi {
background : url("kiwi.svg") no-repeat left left ;
}
L'incontournable référence "When can I use..." permet de voir un état des lieu exhaustif au sujet de l'implémentation de SVG sur les différents navigateurs.
Navigateurs | Versions | Support basique | Dans <img> | CSS background | Élément SVG inline | Effet SVG | SMIL |
---|---|---|---|---|---|---|---|
Firefox | 3.6 | 4 | 4 | 4 | 3.6 | 8 | |
Chrome | 16 | 4 | 5 | 7 | 16 (partiel) | 16 | |
Internet Explorer | 9 | 9 | 9 | 9 | 9 (partiel) | / | |
Opera | 11.6 | 9 | 9.5 | 11.6 | 11.6 (partiel) | 11.6 | |
Safari | 3.2 | 4 | 5 | 5.1 | 4 (partiel) | 4 (partiel) |
SMIL est une spécification du W3C qui décrit le déroulement temporel et spatial des différents composants intégrés, autrement dit les animations
Comme on peut le voir SVG et son système d'animation est plutôt bien implémenté dans les navigateurs actuels. On regrettera Internet Explorer qui traîne à implémenter la spécification SMIL même sous la version 10. On notera aussi le retard de Chrome au niveau des possibilités plus avancées de SVG telles que les masques, les filtres, les transformations, etc.
Voici la structure de base d'un fichier type SVG :
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300px" height="200px" xml:lang="fr"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>La kiwiParty, le web pulpeux</title>
<desc>Un logo animé en SVG</desc>
</svg>
Si cette syntaxe vous semble familière c'est tout à fait normal : SVG s'appuie sur XML, famille sur laquelle est construite d'autres langages de balisage tels que XHTML.
Décomposons les différentes parties :
<?xml version="1.0" encoding="utf-8"?>
Tout document XML commence par ce que l'on appelle un prologue XML qui va indiquer la version utilisée ainsi que l'encodage, de préférence UTF-8 (il faut donc veiller à ce que l'éditeur utilise bien cette page de code pour le fichier).
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
Vient ensuite le fameux doctype qui va spécifier aux navigateurs qu'ici on parle le SVG.
<svg width="400px" height="300px" xml:lang="fr"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
À l'instar de l'élément html
, <svg>
représente la racine de notre document. C'est elle qui va contenir toutes les descriptions des formes graphiques affichées à l'écran.
<title>La kiwiParty, le web pulpeux</title>
<desc>Un logo animé en SVG</desc>
On peut également spécifier <title>
et <desc>
qui permettront de donner un titre et une description au document. Ces balises sont notamment utiles pour le référencement et certains agents utilisateurs.
SVG propose plusieurs moyens de créer des formes, simples ou plus complexes. Chaque forme et plus généralement chaque élément SVG peut être accompagné d'attributs qui vont en décrire les propriétés.
Pour dessiner un rectangle, on utilise la balise <rect>
en spécifiant sa longueur et sa largeur avec les attributs width
et height
. Les attributs x
et y
indiquent la position (horizontale et verticale) au sein de notre élément svg
.
<rect x="25px" y="25px" width="150" height="100"/>
<rect x="200px" y="75px" width="150" height="100"/>
L'unité utilisée ici est le px
(pixel). Il est possible de ne pas la préciser, le parseur l'aurait compris ainsi par défaut. D'autres unités sont envisageables, principalement les mêmes qu'en CSS. Étant donné qu'aucune couleur n'a été précisée, le rectangle se retrouve noir.
Pour dessiner un cercle rien de plus simple avec la balise circle
. L'attribut r
spécifie le rayon du cercle, et les attributs cx
et cy
les coordonnées du centre.
<circle cx="110" cy="110" r="50" />
Pour créer une ligne on utilise l'élément line
qui nécessite quatre paramètres obligatoirement.
x1
: spécifie la position du premier point sur l'axe des abscisses ;x2
: spécifie la position du second point sur l'axe des abscisses ;y1
: spécifie la position du premier sur l'axe des ordonnées ;y2
: spécifie la position du second point sur l'axe des ordonnées ;<line x1="50" y1="50" x2="150" y2="150" stroke="black" stroke-width="2" />
<line x1="100" y1="50" x2="200" y2="150" stroke="red" stroke-width="10" />
<line x1="150" y1="50" x2="250" y2="150" stroke="blue" stroke-width="5" stroke-dasharray="5,3,2" />
L'apparence du trait est définie par les attributs de couleur (stroke
), de largeur (stroke-width
) ou de pointillés (stroke-dasharray
).
Notez que l'écriture avec l'attribut style
est équivalente :
<line x1="50" y1="50" x2="150" y2="150" style="stroke:black;stroke-width:2px;" />
<line x1="100" y1="50" x2="200" y2="150" style="stroke:red;stroke-width:10px;" />
<line x1="150" y1="50" x2="250" y2="150" style="stroke:blue;stroke-width:5px;stroke-dasharray: 5,3,2" />
Lorsqu'un trait mesure 1 pixel de large, son style de fin n'a que peu d'importance car il ne se visualise pas. En revanche dès qu'il est plus épais, il sera intéressant de pouvoir définir un style grâce à l'attribut stroke-linecap
: coupé (butt
), carré (square
) ou arrondi (round
).
<line x1="50" y1="50" x2="300" y2="50" stroke="#5a3434" stroke-width="20" stroke-linecap="butt" />
<line x1="50" y1="100" x2="300" y2="100" stroke="#0a989a" stroke-width="20" stroke-linecap="round" />
<line x1="50" y1="150" x2="300" y2="150" stroke="#933c8e" stroke-width="20" stroke-linecap="square" />
Les éléments précédents sont des formes simples qui ne permettent pas de créer des dessins plus complexes. Heureusement SVG a prévu l'élément path
pouvant correspondre à tout type de tracé (chemin). Cet élément n'a qu'un attribut obligatoire : d
(comme data).
<path d="M 100,180 L 140,0 L 180,180 L 220,0 L 260,180 L 300,0 L 330,180" style="fill:none; stroke:black"/>
Moveto
: noté M, prend comme paramètre les coordonnées du premier point du tracé ;Lineto
: noté L, trace une ligne entre les dernières coordonnées mentionnés ;ClosePath
: noté Z, ferme le tracé ;Lineto horizontal
: noté H, raccourci pour noter des lingne horizontales ;Lineto vertical
: noté V, raccourci pour noter des lignes verticales ;Afin de simplifier la tâche il est possible de rendre ces coordonnées relatives. Pour ce faire, il faudra veiller à indiquer les noms de commande en minuscules.
Sachez que l'on peut faire bien plus avec cet élément. Y compris des formes plus fluides notamment grâce aux arcs elliptiques et aux courbes de Bézier, quadratiques et cubiques. La rédaction de telles formes géométriques fait appel à de fortes notions de mathématiques. Si vous avez besoin de formes de ce type, il est plus intéressent de passer par un logiciel de création vectorielle pour ensuite l'enregistrer en SVG. Si vous ouvrez le fichier avec votre éditeur de texte vous pourrez constater qu'un élément path
a été généré.
À toutes ces formes s'appliquent des couleurs de remplissage ou de contours. Les attributs suivants en définissent l'apparence :
stroke
: couleur du contourfill
: couleur de remplissagestroke-opacity
: opacité du contour (de 0 à 1)fill-opacity
: opacité du remplissage (de 9 à 1)
Dans toutes les situations, on peut utiliser des valeurs de couleurs sous forme de noms (blue
, red
, black
) ou de codes couleurs héxadécimaux (#xxxxxx
).
<circle cx="100" cy="100" r="80" stroke="#4b6c0b" fill="#9dcc41" />
<circle cx="150" cy="100" r="80" stroke="#ff6000" fill="orange" fill-opacity="0.5" />
<circle cx="300" cy="100" r="40" stroke="#4b6c0b" stroke-width="20" fill="transparent" stroke-opacity="0.5" />
<circle cx="340" cy="100" r="40" stroke="#4b6c0b" stroke-width="20" fill="transparent" stroke-opacity="0.5" />
Dans le cas présent, les deux premiers cercles disposent par défaut d'un contour de 1 pixel. L'un recouvre l'autre car son opacité de remplissage est de 50% grâce à fill-opacity
. Les deux autres cercles se recouvrent également mais avec une opacité sur le contour (beaucoup plus large, sans remplissage).
id
et class
Comme en HTML, il est possible d'identifier un élément et un groupe d'élément de façon unique avec un id
, ou de façon groupée avec un attribut class
, cela servira notamment lors des événements (début et fin d'une animation), appliquer des masques, des styles CSS, des dégradés, réutiliser des éléments génériques, etc.
g
Permet de regrouper plusieurs formes dans un seul élément afin de pouvoir les réutiliser ensemble par la suite. L'élément g
(group) est souvent accompagné d'un identifiant id
pour le désigner de manière unique.
defs
et use
Dans certaines situations, il sera utile de déclarer (définir) un ensemble de formes ou d'autres informations en tant que modèles. Ceci évite de répliquer plusieurs fois les mêmes tracés et d'aboutir à une lourde redondance du code source. Par défaut, ces formes sont cachées, et regroupées entre les balises <defs>
et </defs>
. Grâce à use
il est ensuite possible de réutiliser ces ensembles, par exemple en les affichant à des coordonnées différentes.
<defs>
<g id="tete">
<circle cx="40" cy="30" r="40" style="stroke:black; stroke-width: 1px;fill: #F4F4F4;" />
<rect width="100" height="75" x="-10" y="-20" style="fill:#F4F4F4"/>
<circle cx="40" cy="30" r="50" style="stroke:black; stroke-width: 1px;fill: none;" />
<circle cx="20" cy="20" r="20" />
<circle cx="60" cy="20" r="15" />
<circle cx="35" cy="20" r="5" style="fill:white"/>
<circle cx="50" cy="20" r="4" style="fill:white" />
</g>
</defs>
<use xlink:href="#tete" x="0" y="30" />
<use xlink:href="#tete" x="0" y="140" />
<use xlink:href="#tete" x="-100" y="80" />
<use xlink:href="#tete" x="100" y="80" />
L'attribut style est applicable aux objets SVG. Il y a trois façons d'intégrer du style, comme en HTML.
Attention, cette pratique n'est pas toujours recommandée, les créateurs SVG préconisent plutôt de passer par les attributs SVG plutôt que d'embarquer tout le style dans l'attribut du même nom.
Le style en ligne permet de déclarer grâce à l'attribut style
d'un élément une série de déclarations de style.
<rect x="25px" y="25px" width="200" height="100" style="fill:pink" />
Avec la balise style
nous pouvons, comme en HTML déclarer une feuille de style interne qui devra être nécéssairement enfant direct de l'élement svg
. Il faudra veiller également à baliser le contenu grâce à une section CDATA
. On précisera également son type MIME.
Rappel : CDATA fait partie de la syntaxe XML et permet d'éviter de devoir échapper les caractères spéciaux.
<svg>
<title>Le web pulpeux</title>
<style type="text/css">
<![CDATA[
#rect {
fill : pink;
}
]]>
<rect x="25px" y="25px" width="100" height="50" id="rect" />
</svg>
Avec SVG, pas de balise link
comme HTML pour faire le lien vers le fichier externe, mais on utilise, ce qu'on appel dans le jargon XML, une PI. Tout ce que vous devez savoir c'est qu'elle possède deux attributs obligatoires, href
et type
.
<?xml-stylesheet type="text/css" href="styleSVG.css"?>
Cette dernière méthode, à l'instar des feuilles de styles CSS est la plus souple. Si vous souhaitez avoir une approche modulaire c'est avec cette méthode qu'il faudra travailler.
Les exemples suivants feront néanmoins appel aux styles en ligne dans un souci de lisibilité du code proposé.
Une fois le fichier CSS lié à SVG, il faut faire appel à des propriétés. Celles-ci sont spécifiques et ne sont pas transposables directement depuis ce que l'on connaît déjà du côté de HTML. L'exemple suivant utilise un fond vert avec une bordure noire de 2 pixels.
<rect x="25px" y="25px" width="100" height="50" id="rect" />
#rect {
fill: #B5CC45;
stroke: black;
stroke-width: 2px;
}
Cet article est une introduction à SVG, si vous souhaitez découvrir les autres propriétés de style utilisables, consultez la documentation officielle du W3C au sujet des styles SVG ou encore la version française.
SVG propose plusieurs solutions afin de créer des animations :
transition
et animation
.Dans cet article consacré à SVG seront abordées les animations SMIL.
Développé par le W3C, le langage SMIL permet de changer les données graphiques vectorielles dans le temps. Il représente un jeu de fonctions d'animations XML. Concrètement, ses balises sont placées comme enfants directs de l'élément sur lequel on souhaite agir. Une propriété n'a pas besoin d'être déclarée pour pouvoir être animée.
animate
Utilisé pour animer un seul attribut ou une seule propriété au cours du temps.
<rect width="100" height="50">
<animate attributeName="width" attributeType="XML"
fill="freeze"
from="0" to="300"
begin="0s" dur="3s"/>
</rect>
Un zeste de JavaScript et l'on peut obtenir une magnifique barre de chargement. SI vous êtes vigilants, vous aurez remarqué que rect
n'est plus une balise auto-fermante. En effet maintenant elle est devenue une balise ouvrante/fermante pour contenir animate
.
Voici les attributs utilisés :
attributName
: spécifie l'attribut ou la propriété CSS à animer ;attributType
: spécifie le type de nœud à traiter ;fill
: permet de geler l'animation arrivée à sa fin ;from
: la valeur de départ de l'animation ;to
: la valeur finale à atteindre ;begin
: l'instant de départ de notre animation;dur
: la durée de notre animation;
On peut également commencer et finir une animation en fonction du début ou de la fin d'une autre animation, pour les faire de succéder. Afin d'obtenir cet effet, il faut renseigner l'animation incriminée par un id
, pour ensuite passer cet id
comme valeur de la propriété begin
de l'animation que l'on souhaite démarrer. On utilise également un pseudo « écouteur d'évènement » pour déclencher l'action.
Un exemple vaut mieux qu'un long discours :
<rect width="100" height="50">
<animate attributeName="width" attributeType="XML" id="rect1"
fill="freeze"
from="0" to="150"
begin="0s" dur="1s"/>
</rect>
<rect y="50" x="150" width="0" height="50" >
<animate attributeName="width" attributeType="XML" id="rect2"
fill="freeze"
from="0" to="150"
begin="rect1.end" dur="1s"/>
</rect>
<rect y="100" x="0" width="0" height="50" >
<animate attributeName="width" attributeType="XML" id="rect3"
fill="freeze"
from="0" to="150"
begin="rect2.end" dur="1s"/>
</rect>
<rect y="150" x="150" width="0" height="50">
<animate attributeName="width" attributeType="XML"
fill="freeze"
from="0" to="150"
begin="rect3.end" dur="1s"/>
</rect>
animateColor
Comme son nom le suggère, cet élément est dédié à l'animation de la couleur. Fonctionnant de la même façon que animate
à cela près que les valeurs de from
et to
doivent être… des couleurs ! Cependant il semblerait qu'il ne soit pas encore totalement bien interpreté par Firefox.
<rect x="15" y="0" width="80" height="200" rx="20" ry="20" style="fill:black;"/>
<circle cx="55" cy="40" r="25" style="stroke:black; stroke-width: 1px;fill: #F4F4F4;">
<animateColor attributeName="fill" id="rect1"
repeatDur="3"
from="green" to="yellow"
dur="3s"/>
</circle>
<circle cx="55" cy="100" r="25" style="stroke:black; stroke-width: 1px;fill: #F4F4F4;" >
<animateColor attributeName="fill" id="rect2"
repeatDur="3"
from="yellow" to="orange"
begin="rect1.end" dur="3s"/>
</circle>
<circle cx="55" cy="160" r="25" style="stroke:black; stroke-width: 1px;fill: #F4F4F4;" >
<animateColor attributeName="fill" id="rect3"
repeatDur="3"
from="orange" to="red"
begin="rect2.end" dur="3s"/>
</circle>
Il faut ajouter à cela deux nouveaux attributs :
repeatCount
: Spécifie le nombre de répétitions de l'action, prend comme paramètre soit un entier soit le mot clé indefinite ;repeatDur
: Spécifie la durée durant laquelle se répète l'action, prend comme paramètre soit un entier soit le mot clé indefinite ;set
Cet élément permet de fixer une valeur pendant une certaine durée de temps. Dans cet exemple le rectangle rose est affiché pendant 3 secondes. L'attribut CSS visibility
est modifié pendant ce laps de temps, ensuite il récupère sa valeur initiale déclarée dans l'élément g
.
<g style="visibility: hidden">
<rect x="25px" y="25px" width="200" height="100" style="fill :pink" />
<set attributeName="visibility" attributeType="CSS"
to="visible"
begin="0" dur="3s"/>
</g>
animateTransform
Avant de vous parler de l'animation des transformations, il faut une brève introduction sur le concept de transformations en SVG. Il y a cinq valeurs possibles de transformations pour l'attribut transform
d'un élément SVG :
translate
);rotate
);scale
);skewX
, skewY
);
Ces transformations telles quelles ne sont pas extraordinairement utiles. Mais les transformations peuvent être animées grâce à l'élément animateTransform
et là cela devient utile ! Pour la mise en œuvre, c'est similaire aux exemples précédents.
<rect width="200" height="100" style="fill:pink" >
<animateTransform attributeName="transform" attributeType="XML" type="translate"
from="-0,0" to="100,0"
begin="0s" dur="2s"
repeatCount="1"
fill="freeze"
/>
</rect>
animatemotion
L'élément animateMotion
permet de faire défiler un objet sur un path
. Il y a deux façons de faire. La première consiste à utiliser un attribut path
dans l'élément animateMotion
dans lequel on renseignera les coordonées du path
. La deuxieme à utiliser la balise mpath
comme enfant direct d'animateMotion
avec l'attribut xlink:href
qui sera lié à l'id
d'un path
existant.
<path id="chemin" d="M 20,20 h 30 v 30 h 30 v 30 h 30 v 30 h 30 v 30 h 30 v 30 h 30 v 30 h 30 v 30" style="fill:none"/>
<g>
<circle r="10" />
<animateMotion begin="0s" dur="10s" repeatCount="indefinite">
<mpath xlink:href="#chemin"/>
</animateMotion>
</g>
SVG est un langage de dessin vectoriel qui offre quelque possibilités d'animation cependant il lui manque de l’interactivité. Le DOM de SVG est conforme aux aspect de la spécifications DOM2. Chaque paramétrage d'attribut et de style est accessible au moyen de JavaScript. On peut donc obtenir toute sorte d'animation et avoir un contrôle très précis sur celles-ci. Afin de s'y adresser on fait souvent appel à des frameworks complets.
Malheureusement, SVG n'est pas directement utilisable sur IE8 et inférieurs. Heureusement des personnes bien intentionnées on réalisé des librairies pour combler ce manque. C'est notamment le cas du célèbre RaphaëlJs qui rend pratiquable SVG sur IE6 et supérieur via JavaScript et l'utilisation de VML. D'autres librairies existent pour les navigateurs n'interprétant pas SMIL (ce qui est de plus en plus rare) notamment FakeSmile.js.
Tutoriel complété par Dew