Découvrir le SVG/Manipulations avancées
Réutilisation d'objets
modifierUn objet peut être réutilisé, « cloné ». Il faut pour cela lui définir un attribut id
(identité), c'est-à-dire lui donner un nom, une étiquette. On peut ensuite utiliser un élément use
et faire référence à cet objet grâce à l'attribut href
de l'espace de nom xlink
.
L'exemple ci-dessous dessine un rectangle, puis en fait une copie située 60 px plus à droite.
x
et y
sont des coordonnées relatives à l'objet original.<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="106" height="71" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title> Copie d'un rectangle </title>
<desc> Deux rectangles identiques </desc>
<rect
x="0" y="0" width="106" height="71"
stroke="black" fill="none"
/> <!-- Cadre de l'image -->
<rect id="rectangle1"
x="18" y="18" width="36" height="18"
/> <!-- Rectangle de base -->
<use xlink:href="#rectangle1" x="60" /> <!-- Copie du rectangle à une abscisse différente -->
</svg>
On peut définir un objet sans le tracer pour ensuite le dupliquer. Cela se fait avec l'élément defs
, qui s'utilise comme l'élément g
. Les éléments defs
devraient se trouver juste après la balise d'ouverture <svg … >
. L'exemple suivant donne le même résultat que ci-dessus :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="106" height="71" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title> Copie d'un rectangle </title>
<desc> Deux rectangles identiques </desc>
<defs>
<rect id="rectangle1"
width="36" height="18"
/> <!-- Rectangle de base -->
</defs>
<rect
x="0" y="0" width="106" height="71"
stroke="black" fill="none"
/> <!-- Cadre de l'image -->
<use xlink:href="#rectangle1" x="18" y="18" /> <!-- Première copie du rectangle -->
<use xlink:href="#rectangle1" x="71" y="18" /> <!-- Seconde copie du rectangle -->
</svg>
Ici, l'objet original a été défini à l'origine (0, 0), les attributs x
et y
de l'élément use
deviennent donc des coordonnées absolues.
À la place de l'élément defs
, on peut utiliser l'élément symbol
qui fonctionne de la même manière. Les deux différences sont que :
- l'identifiant se met directement dans la balise,
<symbol id="…"> … </symbol>
; - lorsque l'on utilise un élément
symbol
, on crée une fenêtre (viewport) à l'intérieur de l'image ; on peut par exemple utiliser les attributspreserveAspectRatio
etviewBox
.
Calques
modifierDe nombreux logiciels de dessin utilisent la notion de « calque » (layer). Un calque est un groupe de figures qui sont ensemble. Il faut imaginer un document comme une superposition de feuilles transparentes, chaque feuille transparente étant un calque. On peut typiquement changer l'ordre d'empilement des calques, certains dessins en cachant d'autres, et l'on peut rendre visible ou invisible un calque (par exemple afficher une grille ou la masquer).
En SVG, il n'y a pas de notion de calque, mais la notion de groupe (élément g
) et de symbole (éléments symbol
) sont équivalentes.
L'ordre des instructions dans le document indique l'ordre dans lequel les éléments sont dessinés ; ainsi, si l'on dessine deux éléments, le deuxième peut recouvrir le premier, le cacher. Ainsi, l'ordre des groupe correspond à l'ordre des calques, le premier groupe du document est le calque du bas et le dernier groupe est le calque du dessus. On peut changer l'ordre des calques en déplaçant les groupes dans le fichier.
Par ailleurs, un groupe peut posséder un attribut visibility
qui permet de le masquer (valeur "hidden"
) ou de l'afficher (valeur "visible"
). S'il s'agit d'un symbole ou d'un groupe mis dans un élément defs
, l'attribut doit avoir la valeur "inherit"
afin que s'applique la valeur définie dans l'appel use
, par exemple :
<symbol
id="rectangle1" visibility="inherit"
>
<rect
width="36" height="18"
/> <!-- Rectangle de base -->
</symbol>
<use
visibility="visible"
xlink:href="#rectangle1" x="18" y="18"
/>
</svg>
Transformations géométriques
modifierAttribut transform
modifier
Nous avons déjà présenté l'attribut transform
précédemment, voir Éléments graphiques > Syntaxe générale et aspect des objets.Nous disposons également des transformations suivantes (les virgules peuvent être omises) :
rotate(angle, cx, cy)
: effectue une rotation de centre (cx, cy), les valeurs étant dans l'unité par défaut, et d'amplitude angle (en degrés par défaut) ;translate(tx, ty)
: effectue une translation de vecteur (tx, ty) ;scale(s)
: effectue une homothétie (changement d'échelle) de facteur s ;scale(sx, sy)
: dilate d'un facteur sx selon l'axe des x et d'un facteur sy selon l'axe y ;skewX(angle)
: incline l'image d'une quantité angle (en degrés par défaut) selon l'axe des x ;skewY(angle)
: incline l'image d'une quantité angle (en degrés par défaut) selon l'axe des y ;matrix(a, b, c, d, e, f)
: effectue l'application linéaire correspondant à la matrice de transformation .
Pour reprendre l'exemple ci-dessus, on pourrait écrire :
<use xlink:href="#rectangle1"
transform="scale(2) rotate(45) translate(18, 18)" />
Concernant la transformation matricielle, si (x0, y0) sont les coordonnées avant transformation et (x1, y1) sont les coordonnées après transformation, on a :
- .
On a donc les équivalences :
Quand une série de transformations est spécifiée, celles-ci sont appliquées de droite à gauche.
<circle r="100" transform="translate(18, 18) scale(2) " />
La séquence équivaut à l'arborescence ci-dessous : les éléments internes étant appliqués avant les éléments englobants.
<g transform="translate(18, 18)"> <!-- en troisième -->
<g transform="scale(2)"> <!-- en deuxième -->
<circle r="100" /> <!-- Interne en premier -->
</g>
</g>
Exemple : création d'une courbe de Koch
modifierLa courbe de Koch est une courbe fractale qui peut se construire en répétant des opérations simples. Le code suivant a été proposé par User:Fibonacci sur Wikimedia Commons. Il consiste à tracer un trait horizontal de longueur arbitraire l0 = 14 et de lui attribuer l'étiquette it0
:
<line x2="14" stroke="#000" stroke-width="10" stroke-linecap="round" id="it0"/>
On remarque ici que l'on a par défaut x1 = 0, y1 = 0, y2 = 0.
Cet objet est ensuite translaté de cette même longueur l0 = 14 puis tourné de –60 ° ; le tout est mis dans un groupe portant l'identifiant it1
:
<g id="it1">
<line x2="14" stroke="#000" stroke-width="10" stroke-linecap="round" id="it0"/>
<use xlink:href="#it0" transform="translate(14)rotate(-60)"/>
</g>
Cet objet it1
est à son tour dupliqué, translaté d'une longueur 3 × l0 = 42 et retourné horizontalement par la commande scale(-1, 1)
. Le tout est mis dans un groupe portant l'identifiant it2
. Et ainsi de suite ; comme on a six étapes récursives, la dernière translation se fait d'une longueur 36 × l0 = 10 206. L'ensemble est ensuite ramené à une échelle permettant de tenir dans la fenêtre de 621 × 180. Le code complet est donc :
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="621" height="180">
<g transform="translate(4,179)scale(0.06)">
<g id="itB">
<g id="itA">
<g id="it9">
<g id="it8">
<g id="it7">
<g id="it6">
<g id="it5">
<g id="it4">
<g id="it3">
<g id="it2">
<g id="it1">
<line x2="14" stroke="#000" stroke-width="10" stroke-linecap="round" id="it0"/>
<use xlink:href="#it0" transform="translate(14)rotate(-60)"/>
</g>
<use xlink:href="#it1" transform="translate(42)scale(-1,1)"/>
</g>
<use xlink:href="#it2" transform="translate(42)rotate(-60)"/>
</g>
<use xlink:href="#it3" transform="translate(126)scale(-1,1)"/>
</g>
<use xlink:href="#it4" transform="translate(126)rotate(-60)"/>
</g>
<use xlink:href="#it5" transform="translate(378)scale(-1,1)"/>
</g>
<use xlink:href="#it6" transform="translate(378)rotate(-60)"/>
</g>
<use xlink:href="#it7" transform="translate(1134)scale(-1,1)"/>
</g>
<use xlink:href="#it8" transform="translate(1134)rotate(-60)"/>
</g>
<use xlink:href="#it9" transform="translate(3402)scale(-1,1)"/>
</g>
<use xlink:href="#itA" transform="translate(3402)rotate(-60)"/>
</g>
<use xlink:href="#itB" transform="translate(10206)scale(-1,1)"/>
</g>
</svg>
Fenêtre (viewport)
modifierCertains éléments créent une fenêtre (viewport) : svg
(crée la fenêtre cadre), symbol
(voir ci-dessus), image
et foreignObject
.
Les limites de cette fenêtre peuvent être définis, comme indiqué précédemment, par les attributs x
, y
, width
et height
(voir Structure d'un fichier SVG > Les attributs de l'élément svg). Cela permet de translater l'objet et le cas échéant de lui appliquer un facteur d'échelle, en fonction de la valeur de l'attribut preserveAspectRatio
(ibid.).
L'attribut viewBox
permet de définir un repère à l'intérieur de cette fenêtre : la syntaxe
viewBox="xmin, ymin, largeur, hauteur"
indique que le point en haut à gauche aura les coordonnées (xmin, ymin) et que le point en bas à droite les coordonnées (xmin + largeur, ymin + hauteur). Notez que les virgules ne sont pas obligatoires.
Ainsi, nous reprenons l'exemple ci-dessous mais en utilisant l'attribut viewBox
pour avoir des valeurs de coordonnées et de longueur en centimètres plutôt qu'en pixels. Notez qu'il faut redéfinir l'épaisseur de trait par défaut (nous prenons ici une épaisseur unité de 0,03 cm).
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="3cm" height="2cm" version="1.1"
viewBox="0 0 3 2"
stroke-width="0.03"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title> Copie d'un rectangle </title>
<desc> Deux rectangles identiques </desc>
<defs>
<rect id="rectangle1"
width="1" height="0.5"
/> <!-- Rectangle de base -->
</defs>
<rect
x="0" y="0" width="3" height="2"
stroke="black" fill="none"
/> <!-- Cadre de l'image -->
<rect
x="0" y="0" width="3" height="2"
stroke="black" fill="none"
/> <!-- Cadre de l'image -->
<use xlink:href="#rectangle1" x="0.5" y="0.5" />
<use xlink:href="#rectangle1" x="2" y="0.5" />
</svg>
Apparence des éléments
modifierMarqueurs
modifierUn marqueur est un symbole graphique qui s'affiche au milieu ou à l'extrémité d'une ligne : triangle (pointe de flèche), carré, disque… On peut ainsi créer un élément marker
et l'utiliser dans un élément path
, line
, polyline
ou polygon
.
L'élément marker
est un « conteneur », à l'image d'un élément g
, qui possède un identifiant (attribut id
). Lorsque l'on dessine la courbe (donc dans l'élément path
, line
…), on place alors un attribut marker-start
(marqueur en début de ligne), marker-mid
(milieu) ou marker-end
(marqueur en fin de ligne) avec la valeur "url(#identifiant)"
.
Par exemple, si l'on désire mettre un disque à chaque extrémité de la ligne, on peut écrire :
<defs>
<marker
id="extremiteDeLigne"
>
<circle
cx="1.5" cy="1.5" r="1"
stroke="none" fill="blue"
/>
</marker>
</defs>
<path
d="M10 50
Q50 10, 75 50"
marker-start="url(#extremiteDeLigne)"
marker-end="url(#extremiteDeLigne)"
stroke="black" stroke-width="5" fill="none"
/>
mais le résultat obtenu n'est probablement pas celui attendu :
- le disque n'est pas centré sur l'extrémité de la ligne mais est décalé ;
- le disque est très petit et si vous augmentez le rayon, vous obtenez un carré à la place.
En effet, le marqueur est affiché dans une fenêtre (viewport) dont la taille est proportionnelle à la largeur du trait de la courbe (ici 5 px) et de dimension 3 × 3 par défaut (c'est-à-dire un carré faisant trois fois l'épaisseur de la ligne).
Le code suivant est plus satisfaisant :
<marker
id="extremiteDeLigne"
markerWidth="5" markerHeight="5"
refX="2.5" refY="2.5"
>
<circle
cx="2.5" cy="2.5" r="2.5"
stroke="none" fill="blue"
/>
</marker>
Les attributs :
markerWidth
etmarkerHeight
définissent une fenêtre de 5 × 5 (par rapport à l'épaisseur du trait) ;refX
etrefY
décalent la fenêtre de ses demi-dimensions afin qu'elle soit centrée sur l'extrémité de la ligne.
Le cercle est ensuite placé au centre de la fenêtre et son rayon est choisi pour qu'il soit inscrit dans la fenêtre ; si l'on trace le périmètre (on définit une couleur par le paramètre stroke
), il faut ajuster le rayon pour que l'épaisseur du trait soit contenue dans la fenêtre.
Le code suivant permet de placer des traits d'arrêt perpendiculaires à la ligne :
<defs>
<marker
id="extremiteDeLigne"
markerWidth="1" markerHeight="10"
refX="0.5" refY="5"
orient="auto"
>
<line
x1="0.5" y1="0" x2="0.5" y2="10"
stroke="black" fill="none"
/>
</marker>
</defs>
<path
d="M10 50
Q50 10, 75 50"
marker-start="url(#extremiteDeLigne)"
marker-mid="url(#extremiteDeLigne)"
marker-end="url(#extremiteDeLigne)"
stroke="black" stroke-width="1" fill="none"
/>
Nous avons utilisé l'attribut orient="auto"
qui permet d'aligner les axes du repère de la fenêtre du marqueur avec la direction locale de la ligne. On peut à la place indiquer une valeur numérique, il s'agit alors de l'angle duquel est tournée la fenêtre par rapport au la page (et non pas par rapport à la direction de la courbe).
display="none"
; c'est le cas s'il est placé dans l'élément defs
.Voici un exemple complet :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="29.7cm" height="21cm" version="1.1"
viewBox="0 0 297 210"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title> Cote d'angle </title>
<desc> Cote d'angle </desc>
<defs>
polygon.fleche {
stroke: none;
fill:black
}
path {
stroke: black;
stroke-width: 0.199;
fill:none
}
text {
font-family: "Liberation Sans", "Nimbus Sans L", Arial, sans-serif
}
]]></style>
<marker
id="fleche1"
markerWidth="10" markerHeight="6.67"
refX="0" refY="3.33"
orient="auto"
>
<polygon class="fleche"
points="0 3.33, 10 0, 5 3.33, 10 6.67"
/>
</marker>
<marker
id="fleche2"
markerWidth="10" markerHeight="6.67"
refX="10" refY="3.33"
orient="auto"
>
<polygon class="fleche"
points="10 3.33, 0 0, 5 3.33, 0 6.67"
/>
</marker>
</defs>
<!-- cote d'angle -->
<path
d="M259.75 182.63
A6 6
0, 0, 0
259.75 176.63"
marker-start="url(#fleche1)"
marker-end="url(#fleche2)"
/>
<text
x="261.44" y="180.89"
font-size="2.7"
text-anchor="start"
>
60°
</text>
</g>
</svg>
Ce code est un extrait de l'image Fichier:Trame isometrique.svg.
Transparence
modifierLes différents objets graphiques peuvent posséder un attribut fill-opacity
dont la valeur peut être :
- un nombre entre 0 et 1 :
fill-opacity="0"
indique un élément totalement transparent,fill-opacity="1"
indique un élément totalement opaque (valeur par défaut) ; - la valeur
fill-opacity="inherit"
: typiquement pour un objet « cloné » par un élémentuse
, utilise l'opacité définie dans l'élémzntuse
.
Dégradés de couleurs
modifierEn SVG, on peut définir deux types de dégradés de couleur : les dégradés linéaires — la couleur change lorsque l'on se déplace dans une direction — et les dégradés radiaux — la couleur change lorsque l'on s'éloigne d'un point.
Un dégradé est représenté par un identifiant. Il peut être appliqué pour le remplissage d'un objet, avec la syntaxe fill="url(#identifiant)"
, ou à son trait avec la syntaxe stroke="url(#identifiant)"
.
Le dégradé peut se représenter comme une échelle de couleurs. Les couleurs de référence sont appelées « arrêts » (stops) et sont caractérisés par :
- leur position sur l'échelle (offset) ;
- la nature de la couleur.
Ainsi, les gradients contiennent au moins deux éléments stop
ayant pour attributs :
offset
: nombre entre 0 et 1, ou bien pourcentage, désignant la position dans l'échelle ; le bas de l'échelle est désigné paroffset="0"
ou bienoffset="0%"
, le haut de l'échelle est désigné paroffset="1"
ou bienoffset="100%"
;stop-color
: couleur habituelle, par exemplestop-color="black"
ou bienstop-color="#000000"
(voir Éléments graphiques > Syntaxe générale et aspect des objets) ;- le cas échéant
stop-opacity
qui définit l'opacité de l'arrêt (voir ci-dessus).
Dégradé linéaire
modifierUn dégradé linéaire est défini par un élément linearGradient
. Cet élément est entre les balises defs
en début de document est possède un identifiant (attribut id
). L'exemple suivant définit un dégradé du bleu au rouge et l'applique à un rectangle :
<defs>
<linearGradient
id="dégradé"
>
<stop offset="0" stop-color="blue" />
<stop offset="1" stop-color="red" />
</linearGradient>
</defs>
<rect id="rectangle1"
x="18" y="18" width="36" height="18"
fill="url(#dégradé)"
/>
On peut également définir le vecteur du gradient sous la forme de quatre attributs x1
, y1
, x2
et y2
: les arrêts à 0 % et à 100 % sont placés respectivement aux points P1(x1, y1) et P2(x2, y2), et les ligne de même couleur sont perpendiculaires à la droite (P1P2). Par exemple, le code suivant fait un dégradé suivant la grande diagonale du rectangle :
<defs>
<linearGradient
id="dégradé"
x1="0" y1="0"
x2="100%" y2="100%"
>
<stop offset="0" stop-color="blue" />
<stop offset="1" stop-color="red" />
</linearGradient>
</defs>
<rect id="rectangle1"
x="18" y="18" width="36" height="18"
fill="url(#dégradé)"
/>
L'élément peut contenir un attribut gradientTransform
qui fonctionne de la même manière que l'attribut transform
des objets graphiques (voir ci-dessus). Cela permet par exemple d'incliner (skew) le dégradé.
Enfin, l'attribut spreadMethod
définit ce qui se passe si l'objet est plus étendu que le dégradé (c'est-à-dire si le vecteur gradient ne couvre pas les abscisses et les ordonnées de 0 à 100 % de l'objet) :
spreadMethod="pad"
: les couleurs aux extrêmes sont étendues jusqu'aux bords de l'objet ;spreadMethod="reflect"
: le dégradé part dans l'autre sens ;spreadMethod="repeat"
: le dégradé recommence, il se répète.
Dégradé radial
modifierUn dégradé radial s'obtient avec l'élément radialGradient
. Les attributs spécifiques sont :
cx
,cy
etr
: paramètre du disque contenant le dégradé ; l'arrêt à 100 % se situe sur le périmètre du cercle de centre (cx, cy) et de rayon r ; par défaut, le disque est le plus petit disque contenant l'objet (c'est-à-dire que cx = cy = r = 50 %) ;fx
,fy
: coordonnées du foyer du dégradé ; l'arrêt à 0 % se situe au point de coordonnées (fx, fy) ; par défaut, ce point se situe au centre du disque (fx = cx, fy = cy).
On dispose également des attributs gradientTransform
et spreadMethod
.
Par exemple :
<defs>
<radialGradient
id="dégradé"
>
<stop offset="0" stop-color="blue" />
<stop offset="1" stop-color="red" />
</radialGradient>
</defs>
<rect
x="10%" y="10%" width="80%" height="80%"
fill="url(#dégradé)" stroke-width="3"
/>
Motifs
modifierIl est possible de remplir une surface par un motif.
Un motif est un dessin inclus entre les balises d'un élément pattern
. Il s'utilise de la même manière qu'un dégradé.
Par exemple, si l'on veut remplir une surface par des disques bleus :
<defs>
<pattern
id="motif"
x="0" y="0" width="0.1" height="0.1"
>
<circle
cx="5" cy="5" r="3"
fill="blue" stroke="none"
/>
</pattern>
</defs>
<rect
x="10%" y="10%" width="80%" height="80%"
fill="url(#motif)" stroke="black" stroke-width="1"
/>
Les paramètres width
et height
demandent quelques explications. Par défaut, la valeur 1
désigne la dimension totale de l'objet à remplir (largeur totale pour width
, hauteur totale pour height
). En mettant les valeurs 0.1
, nous indiquons que le motif est répété tous les 0,1 dans l'unité locale, c'est-à-dire tous les 1/10 de la largeur et de la hauteur ; cela affiche donc 10 motif dans le sens de la hauteur et 10 motifs dans le sens de la largeur, soit 100 disque sur la surface.
Cette situation peut poser problème : en effet, la taille et les proportions largeur/hauteur du motif dépendent des dimensions de l'objet alors que l'on voudra sans doute que le motif apparaisse tel que dessiné.
On peut indiquer des dimensions « classiques » avec l'attribut patternUnits="userSpaceOnUse"
: les valeurs indiquées dans les attributs width
et height
sont alors la largeur et la hauteur du rectangle dans lequel le motif est dessiné, et la surface est ensuite pavée par ces rectangles. Les dimensins du motif sont alors indépendantes des dimensions de l'objet. Par exemple :
<defs>
<pattern
id="motif"
patternUnits="userSpaceOnUse"
x="7.5" y="7.5" width="15" height="15"
>
<circle
cx="5" cy="5" r="3"
fill="blue" stroke="none"
/>
</pattern>
</defs>
<rect
x="10%" y="10%" width="80%" height="80%"
fill="url(#motif)" stroke="black" stroke-width="1"
/>
Les motifs s'appliquent également aux contours.
Voir aussi : commons:Category:SVG patterns.
Traits et pointillés
modifierLes éléments à une dimension — chemins (path), segments de droite (line), polygones (polyline) — disposent d'un paramètre stroke-dasharray
. Il s'ensuit une liste de nombres séparés par des virgules, qui correspondent à la longueur des segments et des espaces vides. Les nombres peuvent être des longueurs — avec une unité (mm
, in
, px
) ou sans unité pour l'unité par défaut — ou bien des pourcentages — %
—, il s'agit alors du pourcentage de la taille de l'image ou de la boîte englobante (dégradé, motif, masque, filtre).
Exemple
Pour un trait mixte (alternance trait long-trait court) :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- taille visée : format A4 (21 cm × 29,7 cm)
avec 90 dpi, 1cm = 35.43px (arrondi à l'entier le plus proche) -->
<svg width="744" height="1052" version="1.1"
xmlns="http://www.w3.org/2000/svg"
font-family="monospace" font-size="12"
>
<line
x1="0" y1="0" x2="200" y2="200"
stroke="black" stroke-width="1"
stroke-dasharray = "40, 8, 8, 8"
/>
</svg>
Filtres
modifierMasques
modifierAnimation
modifierLe langage SVG dispose d'éléments permettant des faire des animations[1],[2], essentiellement les éléments animate
et animateTransform
. Il faut pour cela que le navigateur gère ces éléments ; c'est le cas de d'Opera, Firefox, Safari et Chrome.
Les éléments graphiques sont définis par des paramètres numériques (position, taille…). L'élément animate
permet de modifier les valeurs de manière continue durant une certaine durée. La syntaxe globale est :
<animate attributeName="paramètre" begin="instantInitial" dur="durée" from="valeurInitiale" to="valeurFinale" />
Elle concerne son parent direct. Par exemple, si l'on veut changer la position d'un rectangle, on écrit :
<rect x="0" y="0" width="5" height="5" stroke="black" stroke-width="1px" fill="none">
<animate attributeName="x"
begin="0s" dur="5s"
from="0" to="10"
/>
</rect>
le rectangle va ainsi passer de la position x = 0 à x = 10 en cinq secondes. Vous remarquerez que la balise rect
a été coupée en deux : <rect…> … </rect…>
au lieu de la balise unique <rect… />
habituelle.
Dans l'élément animate
, l'attribut fill
indique le comportement lorsque l'animation touche à sa fin : "freeze"
pour que l'objet reste dans son état final, "remove"
pour qu'il revienne à son état initial.
Si l'on veut modifier un paramètre de l'attribut transform
, on utilise l'élément animateTransform
.
Exemple complet :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="320px" height="200px" version="1.1"
viewBox="0 0 320 200"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title> Ça bouge ! </title>
<desc> Texte se modifiant de plusieurs manières </desc>
<defs>
<style type="text/css"><![CDATA[
text {
font-family: "Liberation Serif", "Times New Roman", serif;
font-size: 20
}
]]></style>
</defs>
<!-- le texte bouge de droite à gauche -->
<text x="0" y="15">
<animate attributeName="x"
begin="0s" dur="5s"
fill="freeze"
from="200" to="0"
/>
Ça bouge !
</text>
<!-- le texte passe du bleu au rouge -->
<text x="0" y="35">
<animate attributeName="fill"
begin="0s" dur="5s"
fill="freeze"
from="#0000ff" to="#ff0000"
/>
Ça bouge !
</text>
<!-- le texte grossit -->
<text x="0" y="55">
<animate attributeName="font-size"
begin="0s" dur="5s"
fill="freeze"
from="1" to="16"
/>
Ça bouge !
</text>
<!-- le texte tourne -->
<g transform="translate(120, 35)">
<text x="0" y="0" text-anchor="middle">
<animateTransform attributeName="transform"
type="rotate"
begin="0s" dur="5s"
fill="freeze"
from="0" to="360"
/>
Ça bouge !
</text>
</g>
</svg>
Plutôt que de mettre l'élément animate
entre les balises ouvrantes et fermantes de l'élément graphique, on peut aussi y faire référence avec un attribut xlink:href
, par exemple :
<rect id="rectangle"
x="0" y="0" width="5" height="5" stroke="black" stroke-width="1px" fill="none"
/>
<animate xlink:href="#rectangle"
attributeName="x"
begin="0s" dur="5s"
from="0" to="10"
/>
Utilisation de styles
modifierLes styles permettent de définir des paramètres par défaut. Lorsque plusieurs objets utilisent les mêmes paramètres (couleur de remplissage, couleur de trait, épaisseur de trait…), il est utile de définir un style. Ainsi, lorsque l'o change le style, cela change l'affichage pour tous les objets, donc :
- cela permet des changement faciles et rapide même lorsqu'il y a de nombreux objets ;
- cela assure une homogénéité au sein du document voire entre les documents (dans le cas d'un feuille de style extérieure) ;
- cela évite les erreurs : une erreur affectant plusieurs objets, elle est repérée beaucoup plus vite.
Style au format CSS
modifier- Pour plus de détails voir : Le langage CSS.
Feuille de style externe
modifierOn peut avoir recours à une feuille de style externe, sous la forme d'un fichier .css
. Par exemple
Fichier monstyle.css
rect {
fill: red;
stroke: blue;
stroke-width: 3
}
Fichier mondessin.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="monstyle.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="3cm" height="2cm" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title> Rectangle </title>
<desc> Un rectangle </desc>
<rect
x="0.5cm" y="0.5cm" width="2cm" height="1cm"
/>
</svg>
Dans le fichier CSS, nous définissons le style par défaut des éléments rect
.
Dans le fichier SVG, nous avons ajouté une référence à la feuille de style : <?xml-stylesheet href="mystyle.css" type="text/css"?>
.
Styles définis dans le fichier SVG
modifierLes styles peuvent être déclarés à l'intérieur du fichier SVG, soit en en-tête, soit dans l'élément lui-même — mais alors le CSS présente peu d'intérêt.
En en-tête du fichier
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="3cm" height="2cm" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title> Rectangle </title>
<desc> Un rectangle </desc>
<defs>
<style type="text/css"><![CDATA[
rect {
fill: red;
stroke: blue;
stroke-width: 3
}
]]></style>
</defs>
<rect
x="0.5cm" y="0.5cm" width="2cm" height="1cm"
/>
</svg>
Dans l'élément
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="3cm" height="2cm" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title> Rectangle </title>
<desc> Un rectangle </desc>
<rect
x="0.5cm" y="0.5cm" width="2cm" height="1cm"
style="fill: red; stroke: blue; stroke-width: 3"
/>
</svg>
Classes
modifierOn peut définir des classes, c'est-à-dire des styles différenciés. Par exemple :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="3cm" height="4cm" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title> Rectangle </title>
<desc> Un rectangle </desc>
<defs>
<style type="text/css"><![CDATA[
rect {
stroke-width: 3
}
rect.rougebleu {
fill: red;
stroke: blue;
}
rect.vertjaune {
fill: green;
stroke: yellow;
}
]]></style>
</defs>
<rect class="rougebleu"
x="0.5cm" y="0.5cm" width="2cm" height="1cm"
/>
<rect class="vertjaune"
x="0.5cm" y="2cm" width="2cm" height="1cm"
/>
</svg>
ou encore :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="3cm" height="4cm" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title> Rectangle </title>
<desc> Un rectangle </desc>
<defs>
<style type="text/css"><![CDATA[
rect {
stroke-width: 3
}
use.rougebleu {
fill: red;
stroke: blue;
}
use.vertjaune {
fill: green;
stroke: yellow;
}
]]></style>
<rect id="modele"
width="2cm" height="1cm"
/>
</defs>
<use xlink:href="#modele"
class="rougebleu"
x="0.5cm" y="0.5cm"
/>
<use xlink:href="#modele"
class="vertjaune"
x="0.5cm" y="2cm"
/>
</svg>
Passage de la souris
modifierL'exemple suivant permet de modifier l'apparence d'objets lorsque le pointeur de la souris survole l'objet (hover)[3].
Fichier SVG :
<svg width="150" height="150" viewBox="0 0 100 100">
<g class="highlight">
<g>
<circle cx="50" cy="50" r="40" />
<text x="50" y="60" text-anchor="middle" fill="#FFF">Hi!</text>
</g>
</g>
</svg>
Fichier CSS :
text {
fill: #FFF;
font: bold 30px sans-serif;
stroke-width: 0;
}
.highlight {
stroke: #0F0;
stroke-width: 0;
transition: stroke-width 300ms;
}
.highlight:hover {
stroke-width: 10px;
}
.highlight:hover text {
stroke-width: 1px;
}
Style au format XSL
modifierLe XSL est un langage permettant de transformer automatiquement du XML, et donc par conséquent du SVG. On peut ainsi utiliser le XSL pour indiquer d'ajouter systématiquement les attributs fill="red" stroke="blue" stroke-width="3"
aux éléments SVG rect
.
On crée pour cela un fichier monstyle.xsl
contenant
<xsl:template match="svg:rect">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="fill">red</xsl:attribute>
<xsl:attribute name="stroke">blue</xsl:attribute>
<xsl:attribute name="stroke-width">3</xsl:attribute>
</xsl:copy>
</xsl:template>
puis on ajoute dans l'en-tête du fichier SVG :
<?xml-stylesheet href="monstyle.xsl" type="application/xml"?>
- Pour plus de détails voir : Programmation XML/XSLT et Programmation XML/XSL-FO.
Métadonnées
modifierLes métadonnées (metadata) sont des informations sur le fichier lui-même. La présence de métadonnées facilite le traitement automatique des données, par exemple leur recensement, leur catégorisation. Le W3C a développé une norme appelée RDF (resource description framework) et sa mise en œuvre dans le XML.
L'intégration de métadonnées nécessite de déclarer les espaces de nom rdf
auquel nous ajoutons rdfs
(RDF schema) et dc
(Dublin core) qui fournissent une syntaxe.
<?xml version="1.0" standalone="yes"?>
<svg width="4cm" height="3cm" version="1.1"
xmlns = "http://www.w3.org/2000/svg">
<desc>
<title> Le titre </title>
<descr> La description.</descr>
</desc>
<metadata>
<rdf:RDF
xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs = "http://www.w3.org/2000/01/rdf-schema#"
xmlns:dc = "http://purl.org/dc/elements/1.1/" >
<rdf:Description about="http://example.org/myfoo"
dc:title="Le titre"
dc:description="La description"
dc:publisher="Organisation publiant les données"
dc:date="2017-04-11"
dc:format="image/svg+xml"
dc:language="fr" >
<dc:creator>
<rdf:Bag>
<rdf:li>Albane Aaron</rdf:li>
<rdf:li>Bernard Barnier</rdf:li>
</rdf:Bag>
</dc:creator>
</rdf:Description>
</rdf:RDF>
</metadata>
…
</svg>
Si l'on veut ajouter des informations sur la licence, on peut déclarer l'espace de nom c
(Creative Commons) :
<?xml version="1.0" standalone="yes"?>
<svg width="4cm" height="3cm" version="1.1"
xmlns = "http://www.w3.org/2000/svg"
xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#">
<desc>
<title> Le titre </title>
<descr> La description.</descr>
</desc>
<metadata>
<rdf:RDF>
<cc:Work
rdf:about="http://example.org/myfoo">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title> Le titre </dc:title>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
…
</svg>
Liens
modifierL'élément a
permet de rendre un objet cliquable, le clic menant vers une adresse donnée. L'objet est encapsulé entre des balises <a xlink:href="…"> … </a…>
. Par exemple :
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="5cm" height="3cm" viewBox="0 0 5 3" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>Example - un lien sur une ellipse ellipse
</desc>
<rect x=".01" y=".01" width="4.98" height="2.98"
fill="none" stroke="blue" stroke-width=".03"/>
<a xlink:href="http://www.w3.org">
<ellipse cx="2.5" cy="1.5" rx="2" ry="1"
fill="red" />
</a>
</svg>
Notes
modifier- ↑ « Animation (SVG 1.1) », sur W3C (consulté le 1er décembre 2018)
- ↑ « SVG animations », sur SVG WG (consulté le 1er décembre 2018)
- ↑ (en) Jeremie Patonnier, « Re: Good place to be asking non FF SVG questions? », sur Mozilla FireFox dev-tech-svg mailing list sur Google Groupes, (consulté le 1er septembre 2017)