Version en ligne

Tutoriel : Le SVG

Table des matières

Le SVG
Introduction au SVG
SVG : oui ou non ?
La structure d'un document SVG
Incorporer du SVG dans du xHTML
Les formes
Les rectangles
Les ellipses
Les lignes
Les polygones et les lignes brisées
Les tracés
Colorier vos formes
Ajouter du CSS
La couleur
Les dégradés
Les motifs
Les animations
<animate />, la polyvalente
Un raccourci facile
Les tracés de mouvement
Les changements de couleur
Les transformations géométriques
Styliser vos formes
Styles de trait et de remplissage
Les marqueurs
Le texte
Un texte simple
Styliser votre texte
Du texte plus complexe !

Le SVG

Vous avez toujours rêvé de faire du Flash,
mais vous ne voulez pas acheter de logiciel à 700 $ ?
Ce tutoriel est fait pour vous !
Le SVG, abréviation de "Scalable Vector Graphics" (graphiques vectoriels adaptables), est un langage simple qui permet de créer des dessins vectoriels avec rien de plus que... le Bloc-notes !

Introduction au SVG

SVG : oui ou non ?

Dans ce premier chapitre, nous allons commencer notre apprentissage en douceur.

SVG : oui ou non ?

Introduction au SVG La structure d'un document SVG

SVG : oui ou non ?

Le SVG est un langage aux possibilités semblables au Flash.
La question a été discutée maintes fois :

C'est bien ou c'est pas bien ?

Avantages

Désavantages

Pour ma part, je trouve que les désavantages ne sont pas assez nombreux pour renoncer à ce merveilleux langage. :)


Introduction au SVG La structure d'un document SVG

La structure d'un document SVG

SVG : oui ou non ? Incorporer du SVG dans du xHTML

La structure d'un document SVG

Comme je vous l'ai dit le SVG est basé sur le XML.
Donc, tout document SVG doit toujours commencer par la déclaration XML, comme ceci :

<?xml version="1.0" standalone="no"?>

L'attribut standalone="no" indique que le document "ne se tient pas tout seul", il fait référence à des fichiers externes, entre autres une DTD. Une DTD est un fichier qui indique quelles balises ont le droit d'être utilisées, avec quels attributs, etc.

La DTD du SVG s'inclut avec la balise <!DOCTYPE>, comme ceci :

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

Finalement, la balise externe, celle dans laquelle on écrira notre code SVG, est :

<svg>
...
</svg>

Elle a (au moins) 4 attributs :

Récapitulons :

<?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="500" height="500" version="1.1"
xmlns="http://www.w3.org/2000/svg">
...
</svg>
La balise <title>...</title>

Elle se place comme premier enfant de la balise <svg>. Le texte que vous écrivez entre les deux balises <title> sera le titre de votre fichier, qui s'affichera dans la barre de titre de votre navigateur si vous y ouvrez votre document seul.

La balise <defs>...</defs>

En SVG, on a souvent besoin de se référer à des objets, comme par exemple lorsqu'on utilise un dégradé. Dans ces cas-là, on inclut le dégradé dans la balise <defs>, et on le référence avec une URL lorsque l'on veut l'utiliser. Tout objet inclus dans <defs> ne sera pas dessiné directement à l'écran ; il devra être appelé.

La balise <g>...</g>

Cette balise est utilisée pour grouper des éléments, pour pouvoir plus facilement les manipuler en tant que groupe. On place ces éléments entre les balises <g> et </g>.

Exemple final :

<?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="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">

<title>Mon premier document SVG !</title>

<defs>
<!-- Ici, on inclura des éléments
     que l'on veut réutiliser plusieurs fois,
     comme des dégradés, des motifs, etc -->
</defs>

<g>
//Éléments à grouper
</g>

// Éléments seuls
 
</svg>

Remarquez les commentaires, que je vous encourage à utiliser pour rendre vos codes plus lisibles :

Pour enregistrer ce document en SVG, copiez le code dans le Bloc-notes, et enregistrer en .svg.


SVG : oui ou non ? Incorporer du SVG dans du xHTML

Incorporer du SVG dans du xHTML

La structure d'un document SVG Les formes

Incorporer du SVG dans du xHTML

Le langage SVG a été créé pour être utilisé sur le web. Comment ?
Nous pouvons toujours linker depuis notre site web vers un fichier SVG, mais le mieux est d'"embeder" nos documents SVG dans une page web.

Pour ce faire, nous avons 2 méthodes à notre disposition :

La balise embed

Ce n'est pas une balise acceptée par le W3C, mais IE ne reconnaît pas <object> pour le SVG. On l'utilise ainsi :

<embed src="rect.svg" width="300" height="100" 
type="image/svg+xml"
pluginspage="http://www.adobe.com/svg/viewer/install/" />
La balise object

Son fonctionnement est similaire, mais les attributs diffèrent. Me voilà poète ! :p

<object data="rect.svg" width="300" height="100" 
type="image/svg+xml"
codebase="http://www.adobe.com/svg/viewer/install/" />

Différences :

La méthode

Que faire alors ?

On ne peut pas la valider complètement, mais pour la rendre la plus valide possible, on peut utiliser une imbrication. On va inclure <embed /> dans <object>, comme ceci :

<object data="apocalypse.svg" width="100%"
height="100%" type="image/svg+xml">
<embed src="apocalypse.svg" width="500"
height="500" type="image/svg+xml" />
</object>

Comme la page est lue de haut en bas, voilà les étapes effectuées :

  1. si le navigateur reconnaît <object>, il l'affiche, sinon...

  2. si le navigateur ne reconnaît pas <object> (comme IE), il l'ignore, continue de lire et rencontre <embed />, qu'il affiche.

Et voilà. Vous savez maintenant un peu mieux ce qu'est le SVG. Dans le prochain chapitre, nous ferons l'apprentissage des formes, composantes principales des documents SVG.


La structure d'un document SVG Les formes

Les formes

Incorporer du SVG dans du xHTML Les rectangles

Tout document SVG est composé en majorité de formes (rectangles, cercles, etc.). Dans ce chapitre, nous apprendrons ces formes.

Les rectangles

Les formes Les ellipses

Les rectangles

Un rectangle se définit avec une balise <rect />. Il doit avoir 4 attributs :

Un 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 xmlns="http://www.w3.org/2000/svg"
width="800" height="800" >

<rect x="50" y="200" width="250" height="40" />

</svg>

Logiquement, si height et width sont égales, un carré sera dessiné.

Comme vous le voyez, le rectangle est dessiné en noir, car c'est la valeur par défaut. Nous apprendrons à les colorier différemment dans le prochain chapitre, avec du CSS.

On peut aussi rajouter deux attributs, rx et ry, qui sont utilisés pour arrondir les coins du rectangle. Vous pouvez n'en mettre qu'un seul, car l'ordinateur met automatiquement la valeur de celui qui n'est pas défini égale à l'autre :

<?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 xmlns="http://www.w3.org/2000/svg"
width="800" height="800">

<rect x="50" y="200" width="250" height="40" rx="15" />

</svg>

SI vous enregistrez ce code en SVG, et que vous l'ouvrez dans votre navigateur, vous verrez que le rectangle est colorié en noir, car il n'a aucun attribut de style. Nous apprendrons à styliser nos formes dans les prochains chapitres.


Les formes Les ellipses

Les ellipses

Les rectangles Les lignes

Les ellipses

Une ellipse, qui s'inclut avec la balise <ellipse />, doit aussi avoir 4 attributs :

Je suis si gentil que je vous ai fait un beau schéma :

Image utilisateur

Si l'on indique le même nombre dans rx et ry , on obtient donc un cercle.

Exemples :

...
<ellipse cx="125" cy="130" rx="190" ry="45" />

<circle cx="300" cy="350" r="120" />
...

Ici, je ne vous ai pas mis la déclaration XML et le <!DOCTYPE>, je crois que l'on peut s'en passer maintenant.


Les rectangles Les lignes

Les lignes

Les ellipses Les polygones et les lignes brisées

Les lignes

Une ligne, en SVG, se définit à l'aide de la balise <line />. :lol:
On en indique le début et la fin avec 4 attributs.

Petit shéma :

Image utilisateur

Exemple :

...
<line x1="20" y1="80" x2="130" y2="200" />
...

Cette ligne irait du point (20, 80) jusqu'au point (130, 200).


Les ellipses Les polygones et les lignes brisées

Les polygones et les lignes brisées

Les lignes Les tracés

Les polygones et les lignes brisées

Les lignes brisées

Une ligne brisée est un ensemble de droites reliées. C'est la balise <polyline /> qui permet de définir une ligne brisée.
Cette fois, un seul attribut est requis : c'est points. Cet attribut indique les coordonnées de chaque point de la ligne brisée, séparées par des virgules et des espaces.

Un exemple :

...
<polyline points="50,50 200,100 20,200 200,40 300,50 400,60" />
...

Ici, la ligne commencera au point (50,50) puis ira au point (200,100), etc., et finira au point (400,60).

Les polygones

Un polygone ressemble beaucoup à une ligne brisée. Comme elle, il n'a besoin que d'un attribut, points, qui indique les points du polygone. La seule différence est que le navigateur trace lui-même une ligne du dernier point vers le premier point, pour fermer le polygone. On le définit avec la balise <polygon />.

Exemple :

...
<polygon points="0,0 40,20 20,20 20,40 30,50 40,60" />
...

Le polygone commencerait au point (0,0), puis irait jusqu'au point (40,20), etc., irait jusqu'à (40,60), puis le navigateur tracera une ligne de (40,60), le dernier point vers (0,0), le premier point du polygone.


Les lignes Les tracés

Les tracés

Les polygones et les lignes brisées Colorier vos formes

Les tracés

Un tracé est encore plus général qu'une ligne brisée. En effet, il permet non seulement de dessiner des droites, mais aussi des courbes. On l'introduit avec la balise <path />.
C'est l'attribut d qui indique les commandes (lignes, courbes, etc.) à effectuer pour dessiner le tracé. Ces commandes sont très variées. Regardons-les en détails...

La commande moveto (M)

La commande moveto (move to, "bouger vers" en anglais) établit un nouveau point courant. (Je vous expliquerai plus tard ce que c'est.)
On note :

...
<path d="M200,300" />
...

Ici, (200,300) sont les coordonnées du nouveau point courant à établir.

Quel est l'avantage des coordonnées relatives ?

Cela permet de réduire la taille de vos fichiers et à l'ordinateur de faire moins de calculs. Que du bon, quoi ! Je vous encourage donc fortement à utiliser les coordonnées relatives.

Les lignes
La commande lineto (L)

Elle trace une ligne du point courant vers un autre.

Point courant ? o_O Vas-tu enfin nous expliquer ce que c'est ?

C'est simplement la dernière coordonnée indiquée dans l'attribut d. Cela peut être soit un moveto, ou la fin d'une ligne, d'une courbe, etc.

Un exemple :

<path d="M100,100 l400,150"/>

Ce code tracera une ligne du point courant (100,100) vers le point (400,150).

Les commandes H et V

Elles sont utilisées pour dessiner des lignes horizontales (H) et verticales (V) seulement. Je vous encourage aussi à les utiliser car elles réduisent la taille de vos fichiers. Leur fonctionnement est similaire à lineto.

Pour fermer vos tracés (Z)

La commande closepath (Z) est un raccourci qui trace une ligne du point courant vers le point spécifié avec la dernière commande moveto. Il n'a besoin d'aucune coordonnée.

Exemple :

...
<path d="M200,200 l10,10 h10,20 v50,20 z"/>
...

Vous remarquerez que j'ai utilisé des lineto horizontaux et verticaux, et que j'ai utilisé des coordonnées relatives, sauf pour le premier moveto bien entendu.

Les courbes

Les courbes sont un peu plus difficiles à comprendre. En effet, vous devez savoir quel type de courbe vous voulez dessiner. Et il en existe trois.

Les courbes quadratiques de Bézier (Q et T)

Une courbe quadratique de Bézier, ça ressemble à ça :

Image utilisateur

On introduit ce type de courbe avec la commande Q, qui trace une courbe à partir du point courant. Vous devez indiquer deux coordonnées :

Je vois déjà vos yeux s'écarquiller de terreur...

Point de contrôle ? !? o_O :o

Pas de panique, amis Zéros :) ! Je vais tout vous expliquer. Pour vraiment illustrer mes propos, je dirais qu'un point de contrôle est un point qui "tire" sur la courbe. Essayez le code suivant :

<path d="M200,200 q0,100 0,200"/>

Citation : Vous

"Oh l'horreur ! J'ai écrit q et ça me dessine une ligne !"

C'est tout à fait normal. En effet, le point de contrôle est situé sur la ligne imaginaire qui va du point courant vers le point de fin de courbe. Si vous changez les coordonnées du point de contrôle, celui-ci semble tirer la courbe vers lui.

Il existe une autre commande pour dessiner des courbes quadratiques : T. C'est une sorte de raccourci. En effet, vous devez seulement indiquer une coordonnée : le point de fin de la courbe. Le point de contrôle est calculé comme étant le point image selon une symétrie centrale du point de contrôle de la courbe q précédente.

Petit schéma pour les visuels :

Image utilisateur

Et un exemple :

<path d="M200,200 q200,100 0,200 t200,100" />
Les courbes cubiques de Bézier (C et S)

Là, c'est (un peu) plus compliqué ! :( Une courbe de Bézier cubique, comme ça :

Image utilisateur

est introduite avec une commande C, et a besoin de trois coordonnées :

Chaque point de contrôle tire sa moitié de la courbe vers lui.

Exemple :

<path d="M200,200 c200,100 -200,300 200,300" />

Il existe aussi une commande raccourcie, (qui se comporte comme T), mais pour les courbes cubiques ; c'est S. Vous devez indiquer seulement le deuxième point de contrôle et le point de fin de courbe, le premier point de contrôle étant l'image par symétrie centrale du deuxième point de contrôle de la courbe précédente.

Encore un beau schéma :

Image utilisateur

Et l'exemple qui va avec :

<path d="M100,100 c150,-50 100,200 200,200 s0,-100 100,-200" />
Les arcs elliptiques (A)

Un arc elliptique, c'es une partie d'ellipse, comme ceci :

Image utilisateur

C'est la dernière commande que nous apprendrons, et probablement la plus compliquée, car elle nécessite six paramètres (je dis paramètres, car cette fois ce n'est pas seulement des coordonnées comme les autres commandes.)
Les voici :

En code, ça fait comme ceci :

<path d="M200,450 a25,100 -30 0,1 50,-25 " />
Image utilisateur

Voici ce que le navigateur prend en compte pour dessiner un arc elliptique :

Souvent, il advient que 4 arcs soient possibles, sur 2 ellipses différentes, avec ces indications seulement. C'est ici qu'interviennent les valeurs de drapeau-large et de drapeau balayage.
Voilà un petit schéma que j'ai traduit (du W3C) :

Image utilisateur

Bon, je sais que ce chapitre était un peu moche, et décoloré, mais patience...
le plus intéressant reste à venir ! :D
Dans le prochain chapitre, vous apprendrez à ajouter de la couleur, pour égayer un peu vos formes.


Les polygones et les lignes brisées Colorier vos formes

Colorier vos formes

Les tracés Ajouter du CSS

Apprenons maintenant à ajouter un peu de couleur à nos formes !

Ajouter du CSS

Colorier vos formes La couleur

Ajouter du CSS

Eh oui, on utilise le CSS pour ajouter du style aux formes SVG. Quelques propriétés CSS peuvent être utilisées en SVG, mais il existe aussi des propriétés propres à ce langage.

Mais voyons d'abord comment intégrer du CSS dans un document SVG...

Nous avons quatre possibilités :

(Presque) comme en xHTML, quoi ! ;) Voyons chacune de ces méthodes en détails...

Feuille de style externe

On rattache une feuille de style à un document SVG en incluant une déclaration XML de feuille de style :

<?xml-stylesheet href="masuperfeuilledestyle.css" type="text/css"?>

juste après la déclaration XML du document, comme ceci :

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet href="masuperfeuilledestyle.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="800" height="800" 
     xmlns="http://www.w3.org/2000/svg" version="1.1">
<title>Exemple de feuille de style externe</title>
  
<rect x="200" y="100" width="600" height="300"/>

</svg>

L'attribut href pointe vers le chemin de votre feuille de style, ici masuperfeuilledestyle.css, qui serait comme ça :

rect 
{
propriété: valeur;
propriété: valeur;
propriété: valeur;
}

Je vous conseille d'utiliser cette méthode si vous avez plusieurs documents SVG à styler de la même façon.

Feuille de style interne

Pour incorporer une feuille de style dans le document SVG lui-même, vous devez utiliser la balise <style>, mais attention : à l'intérieur de celle-ci, vous devrez écrire votre CSS entre <![CDATA[ et ]]>.

Mais pourquoi donc ? o_O !

En fait, c'est pour indiquer au navigateur que le texte qui suit n'est pas du SVG et n'a donc pas à être lu comme tel. Si vous ne rajoutiez pas ces caractères, le navigateur essaierait de lire le CSS comme étant du SVG et cela générerait tout plein d'erreurs !

Un 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="800" height="500" 
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  
<defs>
    
<style type="text/css"><![CDATA[

rect 
{
propriété: valeur;
propriété: valeur;
propriété: valeur;
}

]]></style>
  
</defs>
  
<rect x="200" y="100" width="600" height="300"/>

</svg>

Vous remarquerez que j'ai inclus <style> dans la balise <defs>. Ce n'est pas obligatoire, mais c'est sémantiquement souhaitable.

Je vous recommande d'utiliser cette méthode si vous avez beaucoup de formes à styler pareillement dans votre document.

Styles inline

Ici, c'est un attribut style que l'on rajoute à la balise à styler. C'est la méthode que j'utilise le plus souvent, car une forme SVG est souvent unique.
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="800" height="500" 
     xmlns="http://www.w3.org/2000/svg" version="1.1">

<defs>
      
</defs>
  
<rect   x="200" y="100" width="600" height="300" 
        style="propriété:valeur; propriété:valeur; propriété:valeur;" />

</svg>
Attributs

C'est une méthode plutôt longue qui consiste à mettre en attribut chaque propriété CSS. Je ne vous conseille pas de l'utiliser. On l'utilise généralement pour faire des retouches. Je vous l'apprends seulement pour que vous ne soyez pas trop déconcertés si vous la rencontrez.
Je vous donne quand même un exemple, on ne sait jamais...

<?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="800" height="500" 
     xmlns="http://www.w3.org/2000/svg" version="1.1">

<defs>
      
</defs>
  
<rect   x="200" y="100" width="600" height="300" 
        propriété="valeur" propriété="valeur" propriété="valeur" />

</svg>

Colorier vos formes La couleur

La couleur

Ajouter du CSS Les dégradés

La couleur

Pour commencer, je vous montre quatre propriétés toutes simples pour colorier vos formes.

Le remplissage

C'est la propriété fill qui permet d'indiquer la couleur de votre forme. (ou de votre texte, mais laissons cela à plus tard !... ;) ).

Comme en CSS traditionnel, vous avez trois façons d'indiquer la couleur :

Je ne vous expliquerai pas en détail chaque méthode, étant donné que M@teo l'a si bien fait ici.
Exemple :

<rect   x="20" y="10" width="200" height="300" 
        style=" fill:#26CD22; " />

Vous pouvez aussi écrire none (aucun remplissage). Dans ce cas, le remplissage de la forme sera transparent.

La couleur du trait

Même façon d'indiquer la couleur, mais cette fois avec la propriété stroke.

<rect   x="20" y="10" width="200" height="300" 
        style=" fill:#26CD22; stroke:#1F56D2" />

none s'applique ici aussi.

Pour l'instant, le trait a 1 pixel de large, car c'est sa valeur par défaut. Nous apprendrons à styliser les lignes plus particulièrement dans un prochain chapitre.

L'opacité

Vous pouvez changer la transparence du remplissage avec la propriété fill-opacity, et la transparence du trait avec la propriété stroke-opacity. Vous indiquez un nombre décimal entre 0 et 1.

<rect   x="20" y="10" width="200" height="300" 
        style=" fill:#26CD22; stroke:#1F56D2; fill-opacity:0.7; stroke-opacity:0.5" />
opacity

Ajouter du CSS Les dégradés

Les dégradés

La couleur Les motifs

Les dégradés

Tout d'abord, sachez qu'il y a deux types de dégradés en SVG :

Image utilisateur
Image utilisateur
Les dégradés linéaires
Inclure le dégradé

On inclut un dégradé linéaire dans la balise <defs>, avec la balise <linearGradient>. Celle-ci a 5 attributs : un id, et x1, y1, x2, et y2, qui servent à indiquer le sens (horizontal, vertical, diagonal) du dégradé. On indique ces valeurs en pourcentages.

Exemple :

<defs>

<linearGradient id="vertbleu" x1="0%" y1="0%" x2="100%" y2="100%">

</linearGradient>
    
</defs>
Les dégradés diagonals

Concrètement, x1 et y1 sont les coordonnées du point de départ du vecteur du dégradé et x2 et y2, les coordonnées de son point de fin. Donc si vous voulez faire un dégradé incliné, comme ceci :

Image utilisateur

vous devrez mettre 0% à x1 et y1 et 100% à x2 et y2.

Les couleurs

Chaque couleur dans le dégradé est introduite à l'aide d'une balise <stop />.
C'est son attribut offset qui détermine (en pourcentage) l'endroit dans le dégradé où la couleur est pure (non mélangée).
On utilise le CSS pour déterminer la couleur ainsi que son opacité, à l'aide des propriétés stop-color et stop-opacity.

Reprenons notre exemple de tout à l'heure et ajoutons-lui des couleurs :

<defs>

<linearGradient id="vertbleu" x1="0%" y1="0%" x2="100%" y2="100%">

<stop offset="0%" style="stop-color:#26CD22;
stop-opacity:1"/>

<stop offset="100%" style="stop-color:#1F56D2;
stop-opacity:1"/>

</linearGradient>
    
</defs>
Utiliser le dégradé

Pour appliquer un dégradé à une forme, on indique son URL à l'aide de son id comme valeur de la propriété fill ou stroke de la forme.

De ke sé ? o_O

<defs>

<linearGradient id="vertbleu" x1="0%" y1="0%" x2="100%" y2="100%">

<stop offset="0%" style="stop-color:#26CD22;
stop-opacity:1"/>

<stop offset="100%" style="stop-color:#1F56D2;
stop-opacity:1"/>

</linearGradient>
    
</defs>
  
<rect   x="20" y="10" width="800" height="300" 
        style=" fill:url(#vertbleu); " />

Ici, j'ai utilisé le dégradé avec fill, mais j'aurais aussi pu l'appliquer au trait de la forme, avec stroke.

Les dégradés radiaux

On introduit un dégradé radial avec la balise <radialGradient>, qui s'inclut elle aussi dans <defs>. Elle a 6 attributs :

Vous devez mettre des valeurs en pourcentage (%) partout, sauf pour l'id.

Pour les couleurs et l'utilisation, c'est comme pour les dégradés linéaires :

<defs>

<radialGradient id="vertrosebleu" r="50%" cx="20%" cy="20%" fy="50%" fx="50%">

<stop offset="0%" style="stop-color:#26CD22;
stop-opacity:1"/>

<stop offset="50%" style="stop-color:#D80E7C;
stop-opacity:1"/>

<stop offset="100%" style="stop-color:#1F56D2;
stop-opacity:1"/>

</radialGradient>
    
</defs>
  
<rect   x="00" y="00" width="800" height="400" 
        style=" fill:url(#vertrosebleu); " />

Quelques exemples :

Image utilisateur

(r="50%" fx="50%" fy="50%" cx="50%" cy="50%")

Image utilisateur

(r="20%" fx="50%" fy="50%" cy="50%" cx="50%")

Image utilisateur

(r="50%" fx="60%" fy="80%" cx="80%" cy="60%")
Exercez-vous avec ces attributs, ça m'a pris à moi aussi un certain temps avant de les assimiler complètement.


La couleur Les motifs

Les motifs

Les dégradés Les animations

Les motifs

Les motifs sont utilisés pour remplir une forme ou son trait avec une image se répétant. On introduit un motif dans la section <defs>, avec la balise <pattern>. Visuellement, un motif est en fait la répétition d'un rectangle à l'infini. <pattern> définit ce rectangle, donc ses enfants sont les éléments à inclure dans le rectangle.

Cette fois, 5 attributs :

Par exemple, si je veux qu'un rectangle soit rempli avec un motif d'ellipse, je peux faire comme suit :

<?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="800" height="800" version="1.1" xml:space="preserve"
xmlns="http://www.w3.org/2000/svg">
<title>Test sur un motif</title>

<defs>

<pattern id="motifdellipse" patternUnits="userSpaceOnUse"
x="0" y="0" width="50" height="50">
<ellipse style=" fill:red; stroke:black; "  
cx="25" cy="20" rx="20" ry="15" />
</pattern> 

</defs>

<rect x="15" y="15" width="400" height="100"
style="fill:url(#motifdellipse);
stroke:#acdc66; fill-opacity:1;
stroke-opacity:01" />

</svg>

Ce qui donnerait ceci :

Image utilisateur

Ici, je l'ai utilisé avec la propriété fill, mais comme pour les dégradés, je peux aussi l'utiliser avec stroke.

Les bitmaps

Une utilisation intéressante des motifs est d'y inclure des images bitmap qui seraient trop longues, voir impossibles à coder en SVG, comme celle-là :

Image utilisateur

Dans ce cas, on doit inclure le fichier avec une balise <image />, qui a cinq attributs :

La seule particularité est [préfixe]:href. En effet, le SVG seul ne permet pas totalement de lier des fichiers. Pour cela, il faut utiliser XLink, un langage qui sert justement à faire des liens entre des fichiers XML. Il faut par conséquent rajouter un namespace à la balise <svg> externe, comme ceci (troisième ligne) :

<svg width="800" height="800" version="1.1" xml:space="preserve" 
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Test sur un motif, avec une image</title>

<defs>

<pattern id="motifdefractale" patternUnits="userSpaceOnUse"
x="0" y="0" width="50" height="37.5" >
<image x="0" y="0" width="50px" height="37.5px" xlink:href="fractale.jpg" />
</pattern>

</defs>

<rect x="15" y="15" width="400" height="100"
style="fill:url(#motifdefractale); 
stroke:#acdc66; fill-opacity:1;
stroke-opacity:1;" />

</svg>

Vous n'êtes pas obligés d'écrire "xlink" comme préfixe, pourvu que vous fassiez attention à l'appeler correctement pour l'attribut href de <image />. Personnellement, je trouve que c'est plus sensé.

L'exemple précédent donnerait ce résultat dans Internet Explorer :

Image utilisateur

Et voilà ! Vous pouvez maintenant dessiner de belles formes pleines de couleurs ! :D


Les dégradés Les animations

Les animations

Les motifs <animate />, la polyvalente

Dans ce chapitre, nous verrons comment animer vos formes !

Nous apprendrons comment réaliser la plupart des transformations géométriques possibles, ainsi que des changements de couleurs, etc.

Le SVG possède cinq balises pour définir des animations. Nous les verrons en détails.

<animate />, la polyvalente

Les animations Un raccourci facile

<animate />, la polyvalente

Théoriquement, une animation est le changement de la valeur d'un attribut, ou d'une propriété CSS, au cours du temps.

La première balise que je vous présente est <animate />, car c'est la plus polyvalente. Elle a un grand nombre d'attributs, et je crois que la meilleure façon de vous les présenter est de partir d'un exemple concret.

Disons donc que nous avons un rectangle,

...
<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;" />
...

et que nous voulons lui faire faire une translation horizontale de 140 pixels vers la droite.

Comment allons-nous procéder ?

Nous allons tout simplement changer la valeur de son attribut x au cours du temps.

Commençons. Comme je vous l'ai dit, on se servira de la balise <animate />.
On a donc déjà ça :

...
<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;" />

<animate />
...

Maintenant, comment faire savoir au programme que c'est le rectangle "rectangleQuiBouge" qui sera animé ?

1 - Pour indiquer la balise cible de l'animation

Nous avons 2 choix.

Maintenant, comment allons-nous faire savoir que c'est l'attribut x de notre rectangle dont nous voulons changer la valeur ?

2 - Pour indiquer l'attribut ou la propriété-cible de l'animation

Cette fois, nous aurons recours à deux attributs de la balise <animate />. Le premier est attributeName. On lui donne comme valeur le nom de l'attribut ou de la propriété CSS dont nous voulons faire changer la valeur. Dans notre exemple, on mettrait donc :

...
<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animate attributeName="x" />
</rect>
...

Mais il faut aussi mettre un deuxième attribut, attributeType. Comme valeur, vous mettez CSS si la valeur de attributeName est une propriété CSS, et vous mettez XML si, comme dans notre exemple, c'est un attribut d'une balise SVG. On aurait donc :

...
<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animate attributeName="x" attributeType="XML" />
</rect>
...

<animate /> permet de changer la valeur d'un attribut seulement. Si vous vouliez faire une translation diagonale, il vous faudrait changer et x et y ; vous auriez donc deux balises <animate /> à créer.

3 - Pour indiquer les valeurs de début et de fin de l'attribut (ou la propriété) cible

La prochaine chose à faire est de faire savoir au programme que nous voulons que notre rectangle parte du point (60,30) pour se rendre au point (200,30). Pour ce faire, nous aurons recours aux attributs from et to de la balise <animate />. Pour from (de, en anglais), vous indiquez la valeur de départ de x (pour nous 60), et dans to (vers, en anglais), vous indiquez la valeur de fin de x (pour nous 200) :

...
<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animate attributeName="x" attributeType="XML" from="60" to="200" />
</rect>
...

Si vous essayez ce code, il ne se passe toujours rien. Pourquoi ? Car, entre autres, vous n'avez pas spécifié quand l'animation doit commencer.

4 - Pour contrôler la synchronisation de l'animation
I - Le début de l'animation

Prochaine étape : indiquer le début de l'animation. Nous allons réaliser ceci grâce à l'attribut begin (en anglais, commencement).
Il existe plusieurs façons d'indiquer le début d'une animation, mais commençons par la plus simple.
Il s'agit ici d'indiquer un temps par rapport à la fin du chargement (loading) de votre document SVG par le programme. Pour indiquer un temps, vous pouvez utiliser trois syntaxes différentes :

Pour en revenir à notre rectangle, on aurait donc :

...
<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animate attributeName="x" attributeType="XML" from="60" to="200" begin="5s" />
</rect>
...

Si vous essayez ce code, ça ne marche toujours pas. Il manque encore un attribut essentiel.

II - La durée de l'animation

Il faut faire savoir au programme en combien de temps le rectangle doit se déplacer du point (60,30) vers le point (200,30). On fait ceci avec l'attribut dur (abréviation de duration, durée en anglais). On indique un temps, comme on a appris à le faire avec begin :

...
<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animate attributeName="x" attributeType="XML" from="60" to="200" begin="5s" dur="3s"/>
</rect>
...

Et voilà ! Notre beau rectangle se déplace tout seul ! Le seul inconvénient, c'est qu'il revient à son point de départ à la fin de l'animation :( . C'est ce que vous vouliez ? Pas de problème :) . Sinon, voyons comment y remédier ;) .

III - L'attribut fill

L'astuce est de rajouter à la balise <animate /> un autre attribut, fill, avec une valeur de freeze. Cela aura l'effet de "geler" l'animation en position finale (d'où le freeze, geler en anglais). Par exemple, pour que notre rectangle reste en position à la fin de sa translation, nous écririons :

...
<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animate id="bougageDuRectangle" attributeName="x" attributeType="XML" from="60" to="200" begin="5s" dur="3s" fill="freeze" />
</rect>
...

La valeur par défaut de fill est remove. L'effet obtenu serait exactement le même que si on ne mettait pas d'attribut fill du tout : notre rectangle ferait sa translation, puis reviendrait à son point de départ.

Et voilà ! Vous venez de terminer votre première animation ! ;)

Mais nous sommes loin d'avoir exploré toutes les possibilités que <animate /> nous offre !

V - L'attribut end

C'est un attribut qui sert à indiquer, à l'aide d'un temps, la fin de l'animation.

Mais... la fin de l'animation est calculée comme étant begin + dur, non ? o_O

En effet. Si vous indiquez dans end une valeur plus petite que begin + dur, l'animation stoppera à ce moment-là. Bon. Je comprends que vous ne voyiez pas vraiment l'utilité de end pour l'instant, mais... patientez. Cette balise nous sera utile très bientôt. Sachez seulement qu'elle peut arrêter l'animation.

IV - Autres manières d'indiquer le début ou la fin d'une animation

Je vous ai dit plus tôt qu'il y avait plusieurs façons d'indiquer le début d'une animation, avec l'attribut begin. Nous allons maintenant en voir trois supplémentaires.

Synchronisation sur d'autres animations
La première méthode que je vous montre ici consiste à indiquer le début d'une animation par rapport au début ou la fin d'une autre animation. Dans ce cas-là, il faudra donner un id à l'animation de référence. Dans begin, on écrirait, par exemple :

...
<animate attributeName="x" attributeType="XML" from="60" to="200" begin="animationDeReference.end+2s" dur="3s" fill="freeze" />
...

Cela aurait pour effet de commencer l'animation 2 secondes après la fin de l'animation dont l'id est "animationDeReference".

Le .end signifie la fin de l'animation. Vous pourriez aussi écrire .begin, ce qui voudrait dire de calculer à partir du début de animationDeReference.

Et vous n'êtes pas obligés d'écrire le +2s. Si vous n'écrivez que animationDeReference.end, cela aurait pour effet de commencer l'animation immédiatement à la fin de animationDeReference.

Bon. Je crois qu'il est temps pour un petit TP.
Vous allez ajouter à notre fichier rectangle un cercle rouge au trait orange, de rayon 15 et situé à (50,70). Ce cercle fera une translation verticale de 100 pixels vers le bas. Cette animation commencera 3 secondes après le début de la translation du rectangle.

Êtes-vous prêts ?
...
Attention !
3, 2, 1, à vos Bloc-notes !

...
...
...

Vous voulez la correction ?

<?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="800" height="800" version="1.1" xml:space="preserve"
xmlns="http://www.w3.org/2000/svg">
<title>Rectangle et cercle qui bougent</title>

<defs>

</defs>

<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animate id="bougageDuRectangle" attributeName="x" attributeType="XML" from="60" to="200" begin="2s"  dur="3s" fill="freeze" />
</rect>

<circle id="cercleQuiBouge" cx="50" cy="70" r="15" style="fill: #F70701; stroke: #FFA200;">
<animate attributeName="cy" attributeType="XML" from="70" to="170" begin="bougageDuRectangle.begin+2s" dur="3s" fill="freeze" />
</circle>

</svg>

N'oubliez pas de rajouter un id à l'animation du rectangle :

...
<animate attributeName="cy" attributeType="XML" from="70" to="170" begin="bougageDuRectangle.begin+2s" dur="3s" fill="freeze" />
...

Mais cette méthode fonctionne aussi avec l'attribut end. La syntaxe est la même que pour begin :

<animate ... end="bougageDuRectangle.begin+4s" ... />

Cette méthode vous sera utile si vous avez plusieurs animations qui doivent se déclencher, par exemple, à 2 secondes d'intervalle. Avouez qu'il est plus facile d'écrire id.end+2s que de calculer à la main chaque temps de début. ;)

Synchronisation sur des événements souris
La deuxième méthode dont je vous parle est encore plus intéressante. Elle permet de commencer (avec begin) ou de terminer (avec end) une animation par rapport à un événement. Par événement, j'entends toute action de la souris : lorsqu'on clique sur une forme, lorsqu'on en survole une autre, etc.

Le principe est le même que pour la méthode précédente : vous devez indiquer dans begin ou dans end un id de référence, suivi d'un point (.) et finalement d'un événement :

<animate ... begin="id.evenement+2s" ... />

Il y a plusieurs événements différents. Les voici :

Deuxième petit TP : vous reprenez votre fichier du rectangle et du cercle et vous le modifiez pour que l'animation du cercle commence lorsque la souris survole le rectangle. Vous faites aussi en sorte que l'animation du rectangle stoppe lorsque l'on clique sur le cercle.

Ready ?
...
Go !

...
...
...

On corrige !

<?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="800" height="800" version="1.1" xml:space="preserve"
xmlns="http://www.w3.org/2000/svg">
<title>Rectangle et cercle qui bougent et interragissent !</title>

<defs>

</defs>

<rect id="rectangleQuiBouge" x="60" y="30" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animate id="bougageDuRectangle" attributeName="x" attributeType="XML" from="60" to="200" begin="2s" end="cercleQuiBouge.click" dur="3s" fill="freeze" />
</rect>

<circle id="cercleQuiBouge" cx="50" cy="70" r="15" style="fill: #F70701; stroke: #FFA200;">
<animate attributeName="cy" attributeType="XML" from="70" to="170" begin="rectangleQuiBouge.mouseover" dur="3s" fill="freeze" />
</circle>

</svg>

Et voilà ! Vous auriez aussi pu utiliser activate à la place de click, dans l'attribut end du rectangle.

Synchronisation sur des événements clavier
Il est aussi possible de faire commencer (mais pas terminer) une animation lorsque l'utilisateur appuie sur une touche particulière du clavier.

Pour ce faire, la syntaxe à utiliser dans begin est la suivante : begin="accesKey(touche)".

accesKey est en anglais et signifie "touche d'accès". Facile, non ? Bien sûr, à la place de touche, vous mettez la touche du clavier à appuyer pour commencer l'animation : s, w, 8, ?, ou ce que vous voulez :

...
<rect id="rectangleQuiBouge" x="60" y="30" width="110" height="150" style="stroke: #0B24BE; fill: #18C20B;">
<animate attributeName="x" attributeType="XML" from="60" to="200" begin="accessKey(y)" dur="3s" fill="freeze" />
</rect>
...

Ici, la translation commencerait lorsque l'on appuierait sur la touche "y".

V - L'attribut restart

Cet attribut peut prendre trois valeurs :

Si vous reprenez votre fichier "Rectangle et cercle qui bougent et interagissent !", et que vous ajoutez restart avec la valeur whenNotActive dans l'animation du cercle, comme ceci :

...
<animate attributeName="cy" attributeType="XML" from="70" to="170" begin="rectangleQuiBouge.mouseover" dur="3s" fill="freeze" restart="whenNotActive" />
...

vous verrez que même si vous survolez le rectangle, vous ne pouvez pas recommencer l'animation du cercle si elle n'est pas terminée.

Conclusion

Et voilà. Je sais que cette sous-partie était un gros morceau, car nous avons vu plusieurs choses d'un coup. Mais ne vous inquiétez pas, nous allons réutiliser une très grosse majorité des attributs que nous venons de voir pour les autres balises d'animation.


Les animations Un raccourci facile

Un raccourci facile

<animate />, la polyvalente Les tracés de mouvement

Un raccourci facile

<set /> est une balise très simple.

Contrairement à <animate />, elle ne peut pas calculer et dessiner les valeurs comprises entre les valeurs de début et de fin de son attribut-cible, et elle n'a donc pas d'attribut dur.

Quelle est donc son utilité, me direz-vous ?

La plupart du temps, elle est utilisée pour cacher une forme ou l'afficher. Pour ce faire, on utilise une propriété CSS, visibility, qui peut avoir trois valeurs :

Un petit exemple pour bien comprendre :

...
<ellipse cx="300" cy="300" rx="70" ry="30" style="fill: #26B90E; stroke: #9A0E9F;">
<set attributeName="visibility" attributeType="CSS" to="hidden" begin="triangle.click" />
<set attributeName="visibility" attributeType="CSS" to="visible" begin="triangle2.click" />
</ellipse>

<path id="triangle" d="M70`40 l-20`30 l40`0 z" style="fill: #F6FF00; stroke: #2B77D5;" />
<path id="triangle2" d="M120`40 l20`30 l20`-30 z" style="fill: #2B77D5; stroke: #F6FF00;" />
...

Appuyer sur le triangle jaune "cachera" la forme, alors que cliquer sur le bleu l'affichera. Bien sûr, vous n'êtes pas obligés d'utiliser des événements dans begin. Un temps fonctionnerait aussi.

Comme vous voyez, on a utilisé les mêmes attributs que pour <animate />, ce qui sera aussi le cas, à peu de choses près, pour les trois autres balises d'animation.


<animate />, la polyvalente Les tracés de mouvement

Les tracés de mouvement

Un raccourci facile Les changements de couleur

Les tracés de mouvement

Dans la première partie de ce chapitre, nous avons réalisé une translation simple : un seul attribut de notre rectangle était modifié. Je vous avais dit que si vous vouliez faire une translation diagonale, vous auriez à insérer deux balises <animate />.

Mais imaginez que vous vouliez faire effectuer une translation comportant des courbes... Il vous serait impossible de le faire avec <animate />. C'est pourquoi il existe une balise qui permet ce genre de translation : <animateMotion /> (motion veut dire mouvement en anglais).

Elle est un peu différente, par contre. Entre autres, elle introduit un nouvel attribut : path. C'est grâce à lui que l'animation pourra se déplacer sur des courbes. En effet, nous allons écrire dans cet attribut un tracé, comme on a appris à le faire dans le chapitre Les formes. C'est sur ce tracé que notre forme se déplacera. (On l'appellera alors tracé de mouvement.) Il n'y aura donc pas d'attributs from et to, ni d'attributeName et d'attributeType.
Par contre, nous utiliserons begin et dur, comme avec <animate /> :

...
<path d="M200`200 c150`-50 100`200 200`200 s0`-100 100`-200" fill="none" stroke="black" /> 

<path id="triangleQuiBouge" d="M200`200 l50`50 l25`-49 z" style="fill:#A23333; stroke: #2439AB;">
<animateMotion begin="0s" dur="5s" path="m0`0 c150`-50 100`200 200`200 s0`-100 100`-200" fill="freeze "/>
</path>
...

Ici, j'ai inclus un tracé au début de mon code, pour que l'on voie mieux comment la forme bouge.

Et c'est également le premier moveto de triangleQuiBouge qui se déplace sur le tracé. Si c'était un rectangle, ce serait son coin supérieur gauche (indiqué avec x et y), et si c'était un cercle ou une ellipse, ce serait son centre (coordonnées indiquées avec cx et cy).

La balise <mpath />

Supposons que vous vouliez faire effectuer le même tracé de mouvement à plusieurs formes. Bien sûr, vous pourriez indiquer le même tracé de mouvement dans les attributs path des balises <animateMotion /> de toutes nos formes, comme ceci :

...
<path d="M20`20 l50`50 l25`-49 z" style="fill:#A23333; stroke: #2439AB;">
<animateMotion begin="0s" dur="5s" fill="freeze"  path="m0`0 c150`-50 100`200 200`200 s0`-100 100`-200" />
</path>

<ellipse cx="150" cy="150" rx="70" ry="30" style="fill: #26B90E; stroke: #9A0E9F;">
<animateMotion begin="0s" dur="5s"  fill="freeze" path="m0`0 c150`-50 100`200 200`200 s0`-100 100`-200" />
</ellipse>

<rect x="360" y="130" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animateMotion begin="0s" dur="5s"  fill="freeze" path="m0`0 c150`-50 100`200 200`200 s0`-100 100`-200" />
</rect>

<circle cx="150" cy="270" r="15" style="fill: #F70701; stroke: #FFA200;">
<animateMotion begin="0s" dur="5s"  fill="freeze" path="m0`0 c150`-50 100`200 200`200 s0`-100 100`-200" />
</circle>
...

Mais il existe une autre méthode, qui diminuera la taille de vos fichiers.
Nous n'allons pas inclure d'attribut path dans nos balises <animateMotion />. Par contre, nous allons ajouter une balise fille <mpath /> à chacune de nos quatre balises <animateMotion />. Elle deviendront alors des balises doubles : <animateMotion>...</animateMotion>.

Les balises <mpath /> n'auront qu'un seul attribut, xlink:href. Comme valeur, vous mettrez l'id d'un tracé que vous inclurez dans <defs>, précédé d'un dièse.

Il ne faudra donc pas oublier de rajouter le namespace de XLink dans la balises <svg>. (Si vous ne vous souvenez plus de XLink et des namespaces, allez relire la sous-partie sur les motifs du chapitre précédent, lorsque je parle des images bitmap.)

Au final, cela nous donnerait ceci :

...
<?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="800" height="800" version="1.1" xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Modele</title>

<defs>
<path id="bellePetiteCourbe" d="m0`0 c150`-50 100`200 200`200 s0`-100 100`-200" /> 
</defs>

<path d="M20`20 l50`50 l25`-49 z" style="fill:#A23333; stroke: #2439AB;">
<animateMotion begin="0s" dur="5s" fill="freeze">
<mpath xlink:href="#bellePetiteCourbe" />
</animateMotion>
</path>

<ellipse cx="150" cy="150" rx="70" ry="30" style="fill: #26B90E; stroke: #9A0E9F;">
<animateMotion begin="0s" dur="5s"  fill="freeze" >
<mpath xlink:href="#bellePetiteCourbe" />
</animateMotion>
</ellipse>

<rect x="360" y="130" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animateMotion begin="0s" dur="5s"  fill="freeze" >
<mpath xlink:href="#bellePetiteCourbe" />
</animateMotion>
</rect>

<circle cx="150" cy="270" r="15" style="fill: #F70701; stroke: #FFA200;">
<animateMotion begin="0s" dur="5s"  fill="freeze" >
<mpath xlink:href="#bellePetiteCourbe" />
</animateMotion>
</circle>

</svg>
...
Rotation sur un tracé de mouvement

Vous avez sûrement remarqué que les formes de l'exemple précédent restent droites alors qu'elles se déplacent sur son tracé de mouvement.
<animateMotion /> a un attribut pour contrôler ce comportement : rotate. Sa valeur par défaut est de 0, et c'est pourquoi les formes ne s'inclinent pas. Si vous mettez un autre angle que 0 comme valeur de rotate, vous verrez que la forme sera inclinée de la valeur de rotate alors qu'elle se déplace sur le tracé de mouvement.

Un exemple :

...
<path d="M0`0 l50`50 l25`-49 z" style="fill:#A23333; stroke: #2439AB;">
<animateMotion begin="0s" dur="5s" fill="freeze" rotate="54" path="m0`0 c150`-50 100`200 200`200 s0`-100 100`-200" />
</path>

Mais l'utilité de rotate ne s'arrête pas là. On peut aussi indiquer une valeur de auto. Dans ce cas, la forme pivotera d'elle-même sur son tracé de mouvement au fur et à mesure qu'elle rencontre des courbes.

En exemple, on aurait donc :

...
<path d="M200`200 c150`-50 100`200 200`200 s0`-100 100`-200" style="fill:none; stroke:black;" /> 

<rect x="0" y="0" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animateMotion begin="0s" dur="5s"  fill="freeze" rotate="auto" path="m200`200s c150`-50 100`200 200`200 s0`-100 100`-200" />
</rect>
...

Au lieu de auto, vous pouvez aussi mettre auto-reverse. Dans ce cas, si on reprend notre code précédent, vous verrez que le rectangle pivote de l'autre côté de la courbe :

...
<path d="M200`200 c150`-50 100`200 200`200 s0`-100 100`-200" style="fill:none; stroke:black;" /> 

<rect x="0" y="0" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">

<animateMotion begin="0s" dur="5s"  fill="freeze" rotate="auto-reverse" path="m200`200s c150`-50 100`200 200`200 s0`-100 100`-200" />
</rect>
...
Répétition d'animation

Nous allons maintenant voir un nouvel attribut, valable pour les cinq balises d'animation. J'aurais pu vous le montrer dans la première partie de ce chapitre, mais je pense que c'était un assez gros morceau pour vous.

Nous allons voir comment gérer la répétition des animations. Pour qu'une animation se répète, on aura recours à l'attribut repeatCount. Vous devez indiquer un nombre qui sera le nombre de fois que l'animation sera répétée. (On appelle cela le nombre d'itérations de l'animation.) Si vous voulez que l'animation se répète à l'infini, vous mettez indefinite.

Exemples :

...
<rect x="0" y="0" width="30" height="20" style="fill: #0B24BE; stroke: #18C20B;">
<animateMotion begin="0s" dur="5s" repeatCount="3" fill="freeze" rotate="auto-reverse" path="m200`200 c150`-50 100`200 200`200 s0`-100 100`-200" />
</rect>
...
...
<path d="M0`0 l50`50 l25`-49 z" style="fill:#A23333; stroke: #2439AB;">
<animateMotion begin="0s" dur="5s" repeatCount="indefinite" fill="freeze" rotate="auto-reverse" path="m200`200 c150`-50 100`200 200`200 s0`-100 100`-200" />
</path>
...

Un raccourci facile Les changements de couleur

Les changements de couleur

Les tracés de mouvement Les transformations géométriques

Les changements de couleur

Bien que <animate /> permette de faire certains changement de couleurs, ce n'est pas bien interprété par les programmes.

C'est pourquoi il existe une balise juste pour les changements de couleurs, <animateColor />. Elle fonctionne exactement de la même façon que <animate /> :

...
<polygon points="50`50 50`200 100`250 200`200 200`100 200`100 200`50" style="stroke: #0795A2; fill: #FFAE00;">
<animate attributeName="fill" attributeType="CSS" from="#FFAE00" to="#CE18D5" begin="0s" dur="10s" fill="freeze" />
<polygon/>
...

La couleur de remplissage du polygone passera ainsi de orange à magenta en 10 secondes.

C'est pas mal, tout ce que j'ai à dire sur <animateColor /> ! :lol:

values et keyTimes

Par contre, c'est l'occasion pour nous d'apprendre deux nouveaux attributs, valables pour toutes les balises d'animations, excepté <animateMotion />.

Je vous parle ici premièrement de l'attribut values. Il sert à indiquer plus qu'une valeur pour l'attribut cible de l'animation. On pourrait donc faire passer le remplissage de notre forme de orange à violet, puis à rouge, et enfin à bleu, tout ça dans la même animation.

Dans values, vous indiquez les différentes valeurs que vous désirez assigner à la propriété-cible, séparées par des points-virgules (;).

...<polygon points="50`50 50`200 100`250 200`200 200`100 200`100 200`50" style="stroke: #0795A2; fill: #FFAE00;">
<animateColor attributeName="fill" attributeType="CSS" values="#FFAE00;#CE18D5;#FF3401;#3366FF" begin="0s" dur="3s" fill="freeze" />
</polygon>
...

Il existe un attribut pour permettre de contrôler plus facilement à combien de temps les différentes valeurs de values doivent apparaître.

Si vous vouliez par exemple, que le polygone soit déjà violet après deux secondes, puis qu'il soit rouge à six secondes et complètement bleu à dix, vous auriez recours à l'attribut keyTimes.

À l'intérieur de celui-ci, c'est encore des valeurs séparées par des points-virgules que vous mettrez, mais cette fois des valeurs de temps. Par contre, ce sont des valeurs de temps relatives à l'animation ; la première valeur doit être 0, qui équivaut à la première valeur de values, lorsque l'animation est à 0%, et la dernière valeur doit être 1, qui équivaut à la dernière valeur de values, lorsque l'animation est à 100%. Entre les deux, vous indiquez des nombres à virgules ; 0.2 pour 20% de l'animation, 0.7 pour 70% de l'animation.

Pour en revenir à mon exemple, c'est-à-dire que le polygone soit violet à deux secondes, puis orange à six et bleu à dix, on écrirait :

<polygon points="50`50 50`200 100`250 200`200 200`100 200`100 200`50" style="stroke: #0795A2; fill: #FFAE00;">
<animateColor attributeName="fill" attributeType="CSS" values="#FFAE00; #CE18D5; #FF3401; #3366FF" keyTimes="0; 0.2; 0.6; 1" begin="0s" dur="10s" fill="freeze" />
</polygon>

Allez, courage, il ne nous reste qu'une seule balise d'animation à voir ! ;)


Les tracés de mouvement Les transformations géométriques

Les transformations géométriques

Les changements de couleur Styliser vos formes

Les transformations géométriques

La balise d'animation <animateTransform /> sert à effectuer des transformations géométriques.

<animateTransform /> aussi fonctionne exactement de la même manière que <animate />. Je ne vous apprendrai donc presque rien de nouveau sur les animations. Par contre, l'attribut dont nous allons modifier la valeur dynamiquement, avec <animateTransform />, est, lui, nouveau.

Je parle ici de l'attribut transform. Il peut s'appliquer à toutes les formes que nous avons apprises jusqu'à maintenant, ainsi qu'aux groupes d'éléments. transform permet d'effectuer cinq transformations différentes, que nous allons voir :

Avant de nous pencher dessus, voilà approximativement ce que vous devriez déjà avoir pour essayer les animations :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" style="fill:#00DA43; stroke:#28601D;">
<animateTransform attributeName="transform" attributeType="XML" from="" to="" begin="1s" dur="5s" fill="freeze" />
</path>
...

Il n'en a pas car il n'en a pas besoin. En effet, nous allons modifier sa valeur par défaut, et tout se fera dans <animateTransform />

Translation

Mais... on a déjà fait des translations dans la première partie de ce chapitre, non ?! Pourquoi apprendre une autre façon ?

  1. Pour vous éviter d'avoir à faire des tracés de mouvements à chaque fois que vous voulez faire faire des translations simple à un tracé. (J'entends par translation simple toute translation verticale, horizontale ou diagonale.) En effet, un tracé n'a pas d'attribut x et y, ni rien d'équivalent. On ne pourrait donc pas utiliser <animate />.

  2. Pour vous éviter d'avoir à écrire deux balises <animate /> à chaque fois que vous voulez faire faire une translation diagonale à une forme. transform fera cela avec une seule balise <animateTransform />.

Pour faire effectuer une translation à notre tracé, nous allons d'abord placer dans <animateTransform /> le type de transformation voulue (en anglais bien sûr), à l'aide de l'attribut type :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" style="fill:#00DA43; stroke:#28601D;">
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="" to="" begin="1s" dur="5s" fill="freeze" />
</path>
...

C'est dans from et to que nous indiquerons le vecteur de la translation x,y.

Si nous voulons que notre tracé fasse un translation de 320 pixels vers la droite et de 240 pixels vers le bas, nous écririons :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" style="fill:#00DA43; stroke:#28601D;">
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0`0" to="320`240" begin="1s" dur="5s" fill="freeze" />
</path>
...
Dans transform...

Bien sûr, vous n'êtes pas obligés d'utiliser transform uniquement pour faire des animations. En effet, cela peut être utile pour faire des ajustements. (Décaler des formes par rapport à leur positions plutôt que changer leurs attributs x et y.) Dans ce cas, c'est dans l'attribut transform des formes que vous devrez indiquer le type, suivi du vecteur de la translation entre parenthèses :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" transform="translate(10`5)" style="fill:#00DA43; stroke:#28601D;">
...
Homothétie

Une homothétie est l'agrandissement ou le rétrécissement d'une forme. Pour faire effectuer une homothétie à une forme, vous devez indiquer scale dans l'attribut type de <animateTransform />, et attention : dans from, vous devez indiquer 1, car 1 signifie 100% de la forme actuelle. Tandis que dans to, vous indiquez le facteur d'homothétie :

Avec ces deux animations, la forme garde ses proportions. Mais vous pouvez aussi la déformer !
Dans ce cas, la valeur de to aura la forme de facteurDHomothétieX,facteurDHomothétieY. Dans les deux exemples précédents, c'est comme si vous aviez seulement indiqué facteurDHomothétieX. Le programme prend alors pour acquis que facteurDHomothétieY est égal à facteurDHomothétieX.

Mais rappelez-vous le cours de maths... l'homothétie se faisait à partir d'un point de référence... Or, on n'a nulle part indiqué ce point...

En effet, le SVG ne gère pas complètement l'animation d'homothéties. Toutes les homothéties sont donc calculées à partir de (0,0). Espérons qu'une prochaine version introduira cette fonctionnalité manquante. (Mais soyons francs, je crois que cela ne vous dérange pas trop, et moi non plus ! :p )

Dans transform...

Encore une fois, il est possible d'utiliser l'homothétie directement dans la forme. La syntaxe est la même que pour translate :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" transform="scale(2`1.5)" style="fill:#00DA43; stroke:#28601D;">
...

Par contre, cette méthode permet de faire une homothétie à partir d'un autre point que (0,0). L'astuce est de faire subir une translation à la forme, avec comme vecteur le point d'homothétie désiré, effectuer l'homothétie, puis faire la translation inverse. Pour réaliser ceci, nous allons mettre dans transform plusieurs commandes de transformation, espacées par des espaces. (J'ai l'impression de me répéter... :-° )

...
<path d="M70`70 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" transform="translate(50`70) scale(3) translate(-50`-70)" style="fill:#00DA43; stroke:#28601D;" />
...
Rotation

Poure faire faire une rotation à une forme, c'est rotate que vous devrez écrire dans type. from et to indiqueront des angles : vous mettrez donc 0 dans from et l'angle de rotation voulu dans to.

...
<path d="M150`150 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" style="fill:#00DA43; stroke:#28601D;">
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="-45" begin="1s" dur="3s" fill="freeze" />
</path>
...

Encore une fois, la rotation s'effectue par défaut à partir de (0,0), mais contrairement à l'homothétie, on peut, cette fois, indiquer un point de rotation différent. Nous allons placer une virgule juste après l'angle de rotation, puis indiquer le point de rotation désiré :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" style="fill:#00DA43; stroke:#28601D; ">
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0`50`50" to="-20`50`50" begin="1s" dur="3s" fill="freeze" />
</path>
...
Dans transform...

Encore une fois, on peut utiliser la rotation directement dans transform :

...
<path d="M150`150 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" transform="rotate(86`50`70)" style="fill:#00DA43; stroke:#28601D;" />
...
Inclinaison

Une inclinaison est un peu plus difficile à expliquer. Et puisqu'une image vaut mieux qu'un long discours...

Inclinaison sur l'axe des x

Un exemple imagé d'inclinaison sur l'axe des x :

Image utilisateur

->

Image utilisateur

On voit bien que la forme est inclinée. Cette inclinaison se mesure en degrés, c'est donc des angles que nous mettrons comme valeur de from et de to. Vous mettez 0 dans from et l'angle d'inclinaison dans to.
L'angle d'inclinaison peut être schématisé comme suit :

Image utilisateur

Notez que les deux côtés de l'angle x passent par le milieu des deux formes, perpendiculairement à l'axe des x.

Pour effectuer une inclinaision sur l'axe des x, c'est skewX qu'il faudra mettre dans l'attribut type de <animateTransform />.

Pour faire l'inclinaison des images, il faudrait écrire :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" style="fill:#00DA43; stroke:#28601D; ">
<animateTransform attributeName="transform" attributeType="XML" type="skewX" from="0" to="45" begin="1s" dur="3s" fill="freeze" />
</path>
...
Inclinaison sur l'axe des y

Exemple illustré :

Image utilisateur

->

Image utilisateur

Le fonctionnement est le même que pour l'inclinaison sur l'axe des x : vous mettez l'angle d'inclinaison dans to.

Image utilisateur

Vous remarquerez qu'encore une fois, les deux côtés de l'angle x passent par le milieu des formes, mais cette fois perpendiculairement à l'axe des y.

Dans l'attribut type, vous indiquez skewY :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" style="fill:#00DA43; fill-opacity:0.5; stroke:#28601D; ">
<animateTransform attributeName="transform" attributeType="XML" type="skewY" from="0" to="45" begin="1s" dur="3s" fill="freeze" />
</path>
...
Dans transform...

Pour utiliser l'inclinaison avec l'attribut transform, c'est l'angle d'inclinaison que nous mettons entre les parenthèses :

...
<path d="M50`50 q30`50 -10`110 q50`40 100`0 q-40`-60 -10`-110 q-40`-30 -80`0 z" transform="skewX(23)" style="fill:#00DA43; 
...

Et voilà ! Maintenant, vous pouvez faire de belles animations, et vectorielles en plus :D : à bas les gif animés :lol: !


Les changements de couleur Styliser vos formes

Styliser vos formes

Les transformations géométriques Styles de trait et de remplissage

Dans ce chapitre, nous allons voir plusieurs nouvelles propriétés CSS pour styliser vos formes (pointillés, "tiretés", etc.).

Nous ferons aussi l'apprentissage des marqueurs, qui sont utiles pour faire, par exemple, des flèches à la fin de vos lignes.

Styles de trait et de remplissage

Styliser vos formes Les marqueurs

Styles de trait et de remplissage

Propriétés de trait

Tout d'abord, faisons une petite révision des propriétés de trait que nous connaissons déjà.

stroke

Spécifie la couleur du trait.
Exemple :

...
<circle r="20" cx="340" cy="230" style="fill:red;stroke:#3BD200;" />...
stroke-opacity

Indique l'opacité du trait :

...
<circle r="20" cx="340" cy="230" style="fill:red;stroke:#3BD200;stroke-opacity:0.7;" />
...

C'est tout ! :p Voyons maintenant LA propriété que -j'en suis sûr- vous attendiez depuis longtemps...

stroke-width

stroke-width est la propriété qui nous permettra de changer l'épaisseur du trait !
Comme valeur, vous devez indiquer une épaisseur en pixels :

...
<circle r="20" cx="340" cy="230" style="fill:red;fill-opacity:0.6;stroke:#3BD200;stroke-width:3;" />
...
stroke-linecap

stroke-linecap est une propriété qui sert à indiquer la façon dont est dessinée la fin d'une ligne, d'une ligne brisée, ou d'un tracé. Trois valeurs sont possibles :

stroke-linejoin

Cette propriété spécifie comment seront dessinés les angles aigus d'un rectangle, d'un polygone, d'une ligne brisée ou d'un tracé. Encore une fois, trois valeurs possibles :

Image utilisateur

Mais... o_O Un seul des angles est pointu ! Les deux premiers sont tronqués ! :( Pourquoi donc ? :o Moi, je m'attendais à ça :

...

stroke-miterlimit

Ce comportement est dû à la valeur par défaut d'une autre propriété : stroke-miterlimit, qui est fixée à 4.

Si vous examinez bien cette image,

Image utilisateur

vous pouvez voir que les pointus des 2 premiers angles se prolongent bien plus loin que la valeur de la propriété stroke-width (ici fixée à 8).

C'est pour cette raison que les créateurs du SVG ont introduit la propriété stroke-miterlimit. Si vous l'ajoutez au style de votre forme et que vous lui mettez une valeur plus grande que 4 (par exemple 10) :

...
<polyline points="50,50 60,90 70,45 80,85 100,75" style="fill:none;stroke:black;stroke-width:8;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:5;" />
...

les angles seront pointus jusqu'au bout, comme ceci :

Image utilisateur
stroke-dasharray

C'est la dernière propriété de trait dont je vous parle, et elle est ma foi très intéressante. Son nom signifie, en anglais, "tableau des tirets de la ligne", et c'est elle qui nous permettra de faire des tiretés et des pointillés avec nos lignes.

Tiretés
L'utilisation de stroke-dasharray est un peu plus compliquée que les autres. Il y plusieurs façons d'indiquer sa valeur, mais commençons par la plus simple : vous allez mettre deux chiffres, séparés par une virgule.

Le premier chiffre indique la longueur du premier trait, le second chiffre, celui du premier espace. Le trait et l'espace sont ensuite répétés le long de la ligne.

Pour vous aider à bien assimiler, voici un code et son résultat, zoomé et annoté :

...
<line x1="20" y1="200" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;stroke-dasharray:10,20;" />
...

Résultat du code :

Image utilisateur

Ceci est une utilisation simple de stroke-dasharray. Car vous pouvez lui mettre plus que deux valeurs, pourvu que le nombre de valeurs soit pair :

...
<line x1="20" y1="200" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;stroke-dasharray:10,20,5,7;" />
...

C'est alors cette liste de valeurs qui sera répétée le long de la ligne.

Résultat du code :

Image utilisateur

Reprenons notre premier code, et rajoutons-lui la propriété stroke-linecap, avec une valeur de round :

...
<line x1="20" y1="200" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;stroke-linecap:round;stroke-dasharray:10,20;" />
...

Résultat du code (les cercles rouges indiquent où devraient se terminer les tirets si stroke-linecap était fixé à butt) :

Image utilisateur

Vous pouvez voir que les ronds augmentent la longueur des tirets, et empiètent dans les espaces, donc diminuent la longueur de ceux-ci.

Pour vous aider à avoir les longueurs que vous désirez vraiment, voici donc les calculs à faire lorsque vous utilisez stroke-dasharray et stroke-linecap avec round ou square :

Effectuons ces calculs sur notre code :

...
<line x1="20" y1="200" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;stroke-linecap:round;stroke-dasharray:3,27;" />
...

Ce qui nous donne le résultat escompté :

Image utilisateur

Pointillés
Bien entendu, pour faire des pointillés sur une ligne, il faudra mettre stroke-linecap à round.
Ensuite, les plus futés d'entre vous auront compris que nous allons mettre 0 comme première valeur de stroke-dasharray, et que nous allons laisser stroke-linecap dessiner ses deux moitiés de cercle qui formeront un cercle complet.

Donc, pour remédier à ce problème, que notre code soit compatible IE et FF et que nos cercles aient vraiment l'air de cercles, nous n'allons pas écrire 0 comme première valeur de stroke-linecap. Mais nous allons écrire un nombre décimal très proche de 0, comme par exemple 0.01 !

...
<line x1="20" y1="200" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;stroke-linecap:round;stroke-dasharray:0.01,17;" />
...

Et ce code fonctionne sur Firefox ! :D

Propriétés de remplissage

Petite révision...

fill

fill permet d'indiquer la couleur de remplissage d'une forme.
Ex :

...
<circle r="20" cx="340" cy="230" style="fill:red;" />
...
fill-opacity

Cette propriété spécifie la transparence du remplissage d'une forme (valeur comprise entre 0 et 1) :

...
<circle r="20" cx="340" cy="230" style="fill:red;fill-opacity:0.5;" />
...

C'est tout ce que nous avons vu jusqu'à maintenant. Voyons maintenant une nouvelle propriété ! :D

fill-rule

fill-rule vous sera utile pour les polygones, les lignes brisées et les tracés. Elle sert à indiquer comment sera dessiné le remplissage d'une forme lorsqu'elle se coupe elle-même, ou lorsqu'un tracé possède des sous-tracés (quand vous avez plusieurs movetos dans votre tracé).

Deux valeurs sont possibles :

L'algorithme mathématique qui spécifie si chaque point est en-dedans ou en-dehors du tracé est assez compliqué, c'est pourquoi je ne vous en fais pas part ici.

Exemples d'utilisation

Ce code :

...
<path d="M104,42 Q49,92 23,170 Q77,85 161,77 C130,80 70,50 51,71 Q78,96 101,144 Q81,92 104,42 Z" style="fill:black;fill-opacity:0.5;fill-rule:nonzero;stroke:#A71212;stroke-width:5;stroke-linejoin:round;" />
...

produira ce résultat :

Image utilisateur

Tandis que ce code :

...
<path d="M104,42 Q49,92 23,170 Q77,85 161,77 C130,80 70,50 51,71 Q78,96 101,144 Q81,92 104,42 Z" style="fill:black;fill-opacity:0.5;fill-rule:evenodd;stroke:#A71212;stroke-width:5;stroke-linejoin:round;" />
...

produira ce résultat :

Image utilisateur

Je vous recommande simplement d'essayer les deux valeurs, et si vous n'obtenez pas le résultat espéré avec les deux propriétés, essayez d'échanger les points de début et de fin de vos lignes et de vos courbes.
Par exemple, ce code :

...
<line x1="20" y1="100" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;" />
...

deviendrait comme ça :

...
<line x1="640" y1="200" x2="20" y2="100" style="fill:none;stroke:black;stroke-width:7;" />
...

Je ne vous promets rien, mais ça peut aider parfois. ;)


Styliser vos formes Les marqueurs

Les marqueurs

Styles de trait et de remplissage Le texte

Les marqueurs

Comme je vous l'ai annoncé en introduisant le chapitre, les marqueurs nous permettront de faire des pointes de flèches à la fin et au début de nos lignes.

Mais les marqueurs ne nous permettent pas seulement de dessiner des flèches, car en fait, un marqueur est simplement une forme qui est dessinée au début ou à la fin d'une ligne. Vous pourrez donc dessiner des marqueurs en cercle, en losange, ou en coeur si ça vous chante ! :lol:
Allons-y sans plus tarder !

Comme un marqueur est un élément que vous allez sûrement utiliser plusieurs fois dans votre document, j'espère que vous vous doutiez que nous allons le placer dans la balise <defs>.

Qu'allons-nous placer dans <defs> ?

Premièrement, nous allons placer une balise de marqueur, dans laquelle vous placerez la forme que vous voulez voir se dessiner à la fin de votre ligne. Cette balise est : <marker>...</marker>.
Ce qui nous donne donc ça :

...
<defs>

<marker>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;" />
...

Je place déjà la ligne à laquelle nous allons associer le marqueur tout à l'heure.

La première chose à faire est d'ajouter un id au marqueur, pour pouvoir l'appeler dans notre ligne, à l'aide de la propriété marker-end. Elle aura pour effet de dessiner le marqueur à la fin de la ligne. Comme valeur, vous indiquez une référence d'URL vers l'id du marqueur.

...
<defs>

<marker id="Triangle">
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />
...

Puis nous pouvons y ajouter une forme, je prendrai en exemple un simple triangle :

...
<defs>

<marker id="Triangle">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />
...

Je diminue de moitié son opacité pour pouvoir mieux la distinguer de notre ligne plus tard.

Ensuite, nous devons indiquer la taille du marqueur. Pour ce faire, nous allons rajouter deux attributs à notre balise <marker> : markerWidth, la largeur du marqueur et markerHeight, la hauteur du marqueur.

Dans notre cas, le marqueur mesure 10*10 pixels, on écrira donc :

...
<defs>

<marker id="Triangle" markerWidth="10" markerHeight="10">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />
...

Mais il nous faut tout de suite rajouter un autre attribut, markerUnits, qui servira à indiquer comment calculer les valeurs de markerWidth et de markerHeight. Deux valeurs sont possibles, mais pour l'instant nous allons mettre userSpaceOnUse.

...
<defs>

<marker id="Triangle" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;marker-end:url(#Triangle);"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;" />
...

Vous pouvez essayer ce code, mais vous verrez qu'il manque encore quelques ajustements.

Résultat du code, zoomé (le cercle rouge indique le point de fin de la ligne) :

Image utilisateur
  1. Le marqueur n'est pas orienté dans le sens de la ligne

  2. Le marqueur n'est pas centré sur la ligne

Pour remédier à la rotation du marqueur, nous allons ajouter un autre attribut à <marker>, orient, avec une valeur de auto. Ceci aura pour effet de l'orienter dans le sens de notre ligne :

...
<defs>

<marker id="Triangle" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />
...

Résultat :

Image utilisateur

Finalement, pour que notre marqueur soit centré sur notre ligne, nous allons utiliser deux autres attributs de <marker>, refX et refY. Ces deux attributs vont indiquer la coordonnée dans la boîte du marqueur qui doit s'aligner exactement avec le point de fin de ligne.
Dans notre cas, ce point est (0,5), on va donc écrire :

...
<defs>

<marker id="Triangle" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto" refX="0" refY="5">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />
...

Ce qui nous donne ce résultat :

Image utilisateur
Les propriétés de marqueurs

Nous avons vu que pour dessiner un marqueur à la fin d'une ligne, on utilisait la propriété marker-end :

...
<defs>

<marker id="Triangle" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto" refX="0" refY="5">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />
...

Pour dessiner un marqueur au début d'une ligne, c'est la propriété marker-start que nous allons utiliser :

...
<defs>

<marker id="Cercle" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="10" markerHeight="10" orient="auto">
<circle cx="5" cy="5" r="5" style="fill:red;fill-opacity:0.5;" />
</marker>

<marker id="Triangle" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto" refX="0" refY="5">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);marker-start:url(#Cercle)" />
...

Remarquez que le point de référence (refX,refY) n'est pas le même pour le cercle, car je désire que ça soit son centre qui soit aligné avec le point de début de ligne :

Image utilisateur
Utilisation de markerUnits avec strokeWidth

Si on reprend notre code de tout à l'heure, et que nous lui rajoutons une deuxième ligne avec une valeur de stroke-width différente, que l'on associe aussi au marqueur,

...
<defs>

<marker id="Triangle" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto" refX="0" refY="5">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />

<line x1="40" y1="250" x2="640" y2="250" style="stroke:black;stroke-width:14;marker-end:url(#Triangle);" />
...

vous pouvez voir que le marqueur reste de la même grandeur pour les deux lignes. Il serait intéressant qu'il change de grosseur en fonction de la propriété stroke-width de la forme.

C'est possible en modifiant la valeur de l'attribut markerUnits du marqueur. Nous allons fixer sa valeur à strokeWidth, ce qui aura pour effet de multiplier les attributs markerHeight, markerWidth, refX, refY, ainsi que le contenu du marqueur par la valeur de la propriété stroke-width de la forme à laquelle le marqueur est associé.

...
<defs>

<marker id="Triangle" markerWidth="10" markerHeight="10" markerUnits="strokeWidth" orient="auto" refX="0" refY="5">
<path d="M0,0 l10,5 l-10,5 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />

<line x1="40" y1="250" x2="640" y2="250" style="stroke:black;stroke-width:12;marker-end:url(#Triangle);" />
...

Résultat (cliquez pour agrandir) :

Image utilisateur

Seulement voilà : à présent, nous n'avons plus la même proportion entre le marqueur et la ligne que lorsque nous mettions markerUnits à userSpaceOnUse, car le marqueur, d'une certaine façon, a été dessiné pour userSpaceOnUse.

Pour remédier à ce problème, donc "convertir" notre marqueur de userSpaceOnUse à strokeWidth, il faut diviser les valeurs de markerHeight, markerWidth, refX, refY ainsi que toute les coordonnées de la forme à l'intérieur du marqueur, par la valeur de stroke-width de la ligne à laquelle le marqueur était associé (alors que l'attribut markerUnits était à userSpaceOnUse). (On peut arrondir 2 chiffres après la virgule.)

10 / 7 = 1.43
5 / 7 = 0.71

Ce qui nous donne ce code :

...
<defs>

<marker id="Triangle" refX="0" refY="0.71" markerUnits="strokeWidth" markerWidth="1.43" markerHeight="1.43" orient="auto">
<path d="M0,0 l1.43,0.71 l-1.43,0.71 z" style="fill:red;fill-opacity:0.5;"/>
</marker>

</defs>

<line x1="40" y1="50" x2="640" y2="200" style="stroke:black;stroke-width:7;marker-end:url(#Triangle);" />

<line x1="40" y1="250" x2="640" y2="250" style="stroke:black;stroke-width:12;marker-end:url(#Triangle);" />
...

Et le résultat escompté :Image utilisateur

Allez, un petit exercice en terminant. :) Allez revoir le marqueur en cercle que j'ai utilisé pour vous montrer la propriété marker-start, et "convertissez-le" en strokeWidth.

Si vous voulez vous exercer encore plus, inventez vos propre marqueurs ! ;)
Quelques idées : flèches plus effilées, coeur, pique, losange, carré... Les possibilités sont infinies !

Et voilà ! Vous avez maintenant de belles formes colorées et stylisées ! :D


Styles de trait et de remplissage Le texte

Le texte

Les marqueurs Un texte simple

La première chose que j'ai à vous dire à propos du texte en SVG est malheureusement une mauvaise nouvelle : le SVG ne gère pas les blocs de texte. :(

En xHTML, nous avons la balise <p> : on peut y écrire autant de texte que l'on désire, puis on lui indique une largeur et une hauteur à l'aide du CSS, et le texte est automatiquement placé pour entrer dans ce bloc.

Ce concept est absent du SVG 1.1 : il ne gère le texte que sur une seule ligne.
Heureusement, nous apprendrons une technique pour contourner cette lacune :) ,
et encore plus heureusement, la prochaine version du SVG, 1.2, devrait corriger cela ! :D

Un texte simple

Le texte Styliser votre texte

Un texte simple

Comme je vous l'ai dit, le SVG ne gère actuellement que le texte sur une ligne.

Voyons donc comment ajouter des lignes de texte dans nos documents !

Un texte simple

La balise à utiliser pour ajouter du texte est... <text> !

...
<text>Du texte en SVG !</text>
...

Bien sûr, rien ne s'affiche car nous n'avons pas indiqué de position pour notre texte. C'est donc ce que nous allons faire, à l'aide des attributs x et y de la balise <text> :

...
<text x="300" y="250">Du texte en SVG !</text>
...

Le point (x,y) indique le point en bas à gauche de la première lettre du texte :

Image utilisateur

C'est tout ce que je vous montre au niveau SVG pour l'instant. Voyons maintenant tout plein de propriétés CSS pour colorier et styliser ce texte ma foi un peu fade !


Le texte Styliser votre texte

Styliser votre texte

Un texte simple Du texte plus complexe !

Styliser votre texte

Stylisons un peu ce texte !
Couleurs de trait et de remplissage

Ici, pas de changement : ce sont exactement les mêmes propriétés que pour toutes les autres formes en SVG.

fill : couleur de remplissage
stroke : couleur du trait

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;">Du texte en SVG !</text>
...

Ici, on ne peut quasiment pas voir la couleur de remplissage, car le texte est trop petit.

Voyons donc comment augmenter sa taille !

Taille du texte

Cela se fera grâce à la propriété font-size.
On lui met une valeur en pixels, mais cette fois il faudra écrire "px" (pour pixel) à la suite de la valeur numérique :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;">Du texte en SVG !</text>
...
Italique

On met un texte en italique avec la propriété font-style.

Comme valeur, on spécifie soit italic pour mettre le texte en italique, ou normal, qui est la valeur par défaut (pas de mise en italique), pour contrer l'héritage.

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-style:italic;">Du texte en SVG !</text>
...
Graisse du texte

(j'adore cette expression ! :p ) Pour indiquer si un texte doit être mis en gras ou non, on utilisera la propriété font-weight.

Encore une fois, deux valeurs possibles :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-weight:bold;">Du texte en SVG !</text>
...
Bonjour, la police !

(ah le folklore québécois ! :D ...)(Ce titre ne parle qu'aux québécois ! :lol: )
Pour indiquer quelle police utiliser pour écrire un texte, c'est la propriété font-family qui nous sera utile.

À l'intérieur de celle-ci, vous devez indiquer une liste de polices.

Si la personne qui visionne votre document n'a pas la première police, son navigateur essaiera la deuxième, s'il ne l'a pas non plus, il essaiera la troisième, si... (enfin bref, vous voyez le concept ;) ).

On termine généralement la liste par le mot-clé serif, qui signifie : "Si tu n'as aucune des polices précédentes, utilise une police standard."

Un exemple :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;">Du texte en SVG !</text>
...

Mais le SVG fait mieux que le xHTML au moins sur un point : il permet d'incorporer nos propres polices ! (avec tout plein de jolis tracés ! :D )
Je vous parlerai peut-être des polices incorporées plus en détails dans un prochain chapitre.

Décoration du texte

En SVG, c'est la propriété text-decoration qui permet de décorer le texte.

Elle peut prendre deux valeurs :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;text-decoration:overline;">Du texte en SVG !</text>
...
Alignement du texte

Par défaut, le point spécifié dans les attributs x et y de la balise <text> indique le point en bas à gauche de la première lettre du texte. Mais il est possible de changer cela, grâce à la propriété text-anchor. Les valeurs possibles pour cette propriété sont :

Voici quelques exemples, ainsi que leurs résultats :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;text-anchor:start;">Du texte en SVG !</text>
...

Résultat :

Image utilisateur
...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;text-anchor:middle;">Du texte en SVG !</text>
...

Résultat :

Image utilisateur
...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;text-anchor:end;">Du texte en SVG !</text>
...

Résultat :

Image utilisateur
Espacement des lettres et des mots

Pour changer l'espacement des mots et celui des lettres, on utilise respectivement les propriétés word-spacing et letter-spacing. Elles demandent toutes deux des valeurs en pixels :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;word-spacing:20;letter-spacing:5;">Du texte en SVG !</text>
...

Ici, les lettres seront espacées de 5 pixels et les mots de 20.

Autres styles de trait

Toutes les propriétés que vous avez apprises dans le chapitre précédent peuvent aussi être utilisées sur du texte !

Exemple :

...
<text x="50" y="250" style="fill:yellow;stroke:#abcdef;font-size:90px;stroke-width:5;stroke-linejoin:round;stroke-linecap:round;stroke-dasharray:5,12;">Du texte en SVG !</text>
...

Résultat :

Image utilisateur

Un texte simple Du texte plus complexe !

Du texte plus complexe !

Styliser votre texte

Du texte plus complexe !

La balise <tspan>
Plusieurs lignes de texte !

Pour commencer cette partie, je vous montre l'astuce permettant de faire du texte sur plusieurs lignes.

Certains de vous diront sûrement :

Citation : Zéros qui ne pensent pas à la sémantique

"Mais nous n'avons qu'à séparer notre texte en plusieurs balises <text>, que l'on positionne différemment à l'aide de leurs attributs x et y !"

Il est vrai que cette façon fonctionne, mais ce serait ne pas respecter la sémantique, car votre texte ne serait pas contenu entièrement dans la même balise.

C'est pourquoi il existe une balise <tspan> (t pour texte). C'est une balise fille de <text>. En fait, elles ont exactement les mêmes attributs. Pratiquement, chaque ligne de votre texte sera incluse entre deux balises <tspan> et </tspan>, auxquelles vous attribuerez des attributs "y" différents.

Exemple :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;">
Du texte en SVG !
<tspan x="300" y="280" style="fill:black;stroke:none;font-size:30px;font-family:'Trebuchet MS', Verdana, serif;">
Et puis ce texte qui le suit,
</tspan>
<tspan x="300" y="310" style="fill:black;stroke:none;font-size:30px;font-family:'Trebuchet MS', Verdana, serif;">
inclus dans des balises &#60;tspan&#62;,
</tspan>
<tspan x="300" y="340" style="fill:black;stroke:none;font-size:30px;font-family:'Trebuchet MS', Verdana, serif;">
ce qui permet de faire plusieurs
</tspan>
<tspan x="300" y="370" style="fill:black;stroke:none;font-size:30px;font-family:'Trebuchet MS', Verdana, serif;">
lignes de texte en respectant</tspan>
<tspan x="300" y="400" style="fill:black;stroke:none;font-size:30px;font-family:'Trebuchet MS', Verdana, serif;">
la s&#233;mantique !
</tspan>
</text>
...

Analysons ce code depuis le début.

  1. D'abord la balise <text>, qui contient la première ligne de texte, avec son style.

  2. Ensuite, plusieurs balises <tspan> positionnées verticalement à 30 pixels l'une de l'autre, grâce à l'attribut y. Leur attribut style est identique.

  3. Finalement, la balise </text>, qui referme le tout !

Mais il y a une petite chose que l'on pourrait améliorer pour rendre ce code encore plus lisible : chaque balise <tspan> a son propre attribut style, mais ils sont tous identiques ; cela ajoute beaucoup de lourdeur au code.

Néanmoins, ces attributs sont nécessaires, car sans eux les différentes lignes de texte prendraient le style de leur balise parente <text>, conformément à l'héritage, ce qui ne produirait pas le résultat voulu.

Nous allons donc ajouter une aute balise <tspan>, englobant toutes les autres. Nous lui donnerons un attribut style, et nous enlèverons tous les autres attributs style des balise <tspan> de lignes.

En l'absence d'attribut style, elles prendront le style de leur parente, qui ne sera pas en l'occurrence <text>, mais plutôt <tspan> :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;">
Du texte en SVG !
<tspan style="fill:black;stroke:none;font-size:30px;font-family:'Trebuchet MS', Verdana, serif;">
<tspan x="300" y="280">
Et puis ce texte qui le suit,
</tspan>
<tspan x="300" y="310">
inclus dans des balises &#60;tspan&#62;,
</tspan>
<tspan x="300" y="340">
ce qui permet de faire plusieurs
</tspan>
<tspan x="300" y="370">
lignes de texte en respectant</tspan>
<tspan x="300" y="400">
la s&#233;mantique !
</tspan>
</tspan>
</text>
...

Mais il reste encore une dernière chose à améliorer avec ce code. En effet, on utilise des positions absolues pour indiquer les positions de chaque ligne. Si on change l'attribut y de la première balise <text>, on n'aura plus les mêmes interlignes.

Pour remédier à cela, nous allons plutôt indiquer les positions des lignes en relatif, à l'aide de l'attribut dy (pour déplacement sur l'axe des Y)de la balise <tspan>.

Celui-ci décale le texte de la ligne à laquelle il est attribué d'un certain nombre de pixels par rapport au dernier attribut y ou dy rencontré.

Pour notre exemple, cela donnerait :

...
<text x="300" y="250" style="fill:yellow;stroke:#abcdef;font-size:50px;font-family:'Trebuchet MS', Verdana, serif;">
Du texte en SVG !
<tspan style="fill:black;stroke:none;font-size:30px;font-family:'Trebuchet MS', Verdana, serif;">
<tspan x="300" dy="30">
Et puis ce texte qui le suit,
</tspan>
<tspan x="300" dy="30">
inclus dans des balises &#60;tspan&#62;,
</tspan>
<tspan x="300" dy="30">
ce qui permet de faire plusieurs
</tspan>
<tspan x="300" dy="30">
lignes de texte en respectant</tspan>
<tspan x="300" dy="30">
la s&#233;mantique !
</tspan>
</tspan>
</text>
...
L'attribut rotate

rotate est un attribut des balises <text> et <tspan>. Il sert à retourner chaque caractère individuellement (plutôt que toute la ligne de texte grâce à l'attribut transform).

Vous lui fournissez une liste de valeurs séparées par des virgules. Le premier nombre correspond à l'angle de rotation du premier caractère, le deuxième nombre à celui du deuxième caractère, etc.

Grâce à lui, on peut faire des effets sympa, comme ceci :

...
<text x="370" y="300" rotate="-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10,-10,10" style="stroke:red;fill-opacity:0.7;fill:#27D210;font-size:40px;stroke-width:1;letter-spacing:3px;text-anchor:middle;">
Un texte retourn&#233; de tous c&#244;t&#233;s !
</text>
...

Résultat :

Image utilisateur
La balise <tref />

Cette balise, fille de <text>, vous servira lorsque vous aurez à utiliser plusieurs fois le même texte dans un document.

Vous placerez ce texte dans une balise <text>, que vous inclurez dans <defs> et à laquelle vous affecterez un id.

Puis, lorsque vous voudrez afficher ce texte à l'écran, vous créerez une balise <text>, que vous positionnerez où vous le voudrez, et que vous styliserez à votre gré (ah ! le poète en moi :lol: ).

C'est à l'intérieur de cette balise <text> que vous placerez une balise <tref /> (pour text reference, référence textuelle en anglais), qui appellera votre texte placé dans <defs> à l'aide de l'attribut xlink:href.

(Eh oui, il faudra rajouter le namespace d'XLink dans la balise <svg> externe. Je vous recommande d'ailleurs de le faire pour tous vos documents à partir de maintenant.)

Voici un exemple (je ne vous mets pas la balise <svg>, mais n'oubliez pas d'y inclure un attribut xmlns supplémentaire pour XLink):

...
<defs>
<text id="texte_repete">Texte r&#233;p&#233;t&#233; plusieurs fois</text>
</defs>

<text x="50" y="50" style="fill:blue;stroke:yellow;stroke-width:0.6;font-size:20px;">
<tref xlink:href="#texte_repete" />
</text>

<text x="220" y="300" style="fill:blue;stroke:yellow;stroke-width:0.6;font-size:20px;">
<tref xlink:href="#texte_repete" />
</text>

<text x="280" y="120" style="fill:blue;stroke:yellow;stroke-width:0.6;font-size:20px;">
<tref xlink:href="#texte_repete" />
</text>

<text x="320" y="410" style="fill:blue;stroke:yellow;stroke-width:0.6;font-size:20px;">
<tref xlink:href="#texte_repete" />
</text>
...
La balise <textPath>

Jusqu'à maintenant, nos lignes de texte étaient droites. Mais il est aussi possible qu'elles suivent un tracé, et donc de les courber, grâce à <textPath>, une balise fille de <text>.

Pour ce faire, nous inclurons dans <defs> le tracé (balise <path />), avec un id.

Ensuite, nous mettrons une balise <text>, hors de <defs>. Cette balise <text> contiendra une balise <textPath>, qui appellera le tracé à l'aide d'xlink:href. C'est donc à l'intérieur de <textPath> que vous écrirez votre texte.

Un exemple complet :

...
<defs>
<path id="trace_ondule" d="M70,230 c150,-50 100,200 200,200 s0,-300 400,-200" />  
</defs>

<text style="fill:#FF9844;stroke:#2742EB;stroke-width:1;font-size:30px;">
<textPath xlink:href="#trace_ondule">Un texte qui ondule le long d'un trac&#233;, pour ensuite y remonter...</textPath>
</text>
...

Comme vous le voyez, la balise <text> n'a pas d'attribut de positionnement. La ligne de texte commence au point (70,230), qui est indiqué dans le premier moveto de trace_ondule.

Plusieurs balises combinées !

Notez que nous pouvons toujours combiner ce que nous apprenons.

Par exemple, on pourrait insérer une balise <tref /> à l'intérieur de <textPath>. À ce moment-là, ce serait le texte contenu dans <defs> qui se dessinerait le long du tracé.

...
<defs>
<path id="trace_ondule" d="M70,230 c150,-50 100,200 200,200 s0,-300 400,-200" />  
<text id="texte_ondule">Un texte qui ondule le long d'un trac&#233;, pour ensuite y remonter...</text>
</defs>

<text style="fill:#FF9844;stroke:#2742EB;stroke-width:1;font-size:30px;">
<textPath xlink:href="#trace_ondule"><tref xlink:href="#texte_ondule" /></textPath>
</text>
...

Et voilà ! Maintenant vous savez ajouter du texte dans des fichiers SVG et le styliser !

Le tutorial n'est pas terminé.
D'autres chapitres arrivent aussi tôt que possible (dès que j'ai le temps).

J'espère que ce tutoriel vous a plu ;) !


Styliser votre texte