Infoforall

9 - Dessin vectoriel avec SVG

Le dessin vectoriel est un type d'objet image particulier. Sous ce format, on ne définit pas l'image comme un ensemble de pixels ayant une couleur particulière mais comme un ensemble d'objets ayant de propriétés. La différence ? Lorsqu'on fait un zoom, on ne perd pas en qualité puisqu'on redéfinit l'image. On évitera ainsi la pixelisation tout en ayant un fichier de petite taille.

Ainsi, on peut définir un objet SVG comme une image contenant un rectangle bleue de taille précise et un cercle jaune ayant une taille deux fois plus petite. Et c'est tout.

Je ne traiterai pas ici longuement de la création de telle image via les logiciels de dessin. Une simple remarque en fin de leçon sur les logiciels libres disponibles, à vous de les installer et de les essayer si cela vous tente.

Cette activité traitera surtout de la création de ces images en utilisant le XML.

Avant de commencer, précisons que ce format est facilement intégrable en HTML, et qu'on peut utiliser CSS et Javascript pour manipuler l'image.

1 - Les cercles avec circle

Le format SVG est basé sur un langage à base de balisage XML, un peu comme le HTML. Il ne s'agit pas d'un langage de programmation mais d'un langage de description, comme le HTML.

SVG veut dire Scalable Vector Graphics. Il a été crée vers 1990 par un groupe d'informaticiens comportant des employés d'IBM, Apple, Microsoft et Xerox.

L'intérêt de ces images est la légerété de stockage quelque soit leurs dimensions. Il y a donc une synergie très grande avec Internet, où la vitesse de téléchargement est un point central.

Scalable veut dire qu'on peut changer leur échelle, sous entendu sans perte de qualité. On le voit souvent traduit par étirable.

Pour insérer facilement une image SVG dans une page HTML, il faut utiliser la balise <svg>...CODE DU SVG...</svg>.

Vous pouvez trouver une structure basique HTML dans la partie FICHES ou ICI.

01° Créer une page HTML en utilisant la fiche ci-dessus puis rajouter, dans la balise section de body, le code suivant :

<svg width= "100" height= "100">

    <circle cx="50" cy="50" r="40" stroke="orange" stroke-width="6" fill="yellow" />

</svg>

Vous devriez obtenir ceci :

Décodons :

Regardons ce que cela donne si on crée une image trois fois plus grande : de 300x300 avec un cercle de 120 pixels en (x=150;y=150) et une bordure de 18, sous entendu pixels.

<svg width="300" height="300">

    <circle cx="150" cy="150" r="120" stroke="orange" stroke-width="18" fill="yellow" />

</svg>

Vous devriez obtenir ceci :

Comme vous le voyez, on a augmenté la taille par trois et l'image est toujous aussi nette.

02° Rajoutez une autre définition de cercle dans la balise svg, par exemple :

<svg width="200" height= "100">

    <circle cx="50" cy="50" r="40" stroke="orange" stroke-width="6" fill="yellow" />

    <circle cx="150" cy="50" r="40" stroke="yellow" stroke-width="6" fill="orange" />

    <circle cx="50" cy="150" r="40" fill="teal" />

</svg>

Vous devriez obtenir cette fois :

On voit donc qu'on a créé une image qui contient trois objets : trois cercles.

Remarque : il est parfois compliqué de comprendre la taille finale du cercle une fois qu'on rajoute la bordure. De base, votre cercle jaune possède un rayon de 40 pixels. Mais la bordure orange est de 6 pixels. LE truc à comprendre est que la bordure de 6 pixels est en réalité une bordure orange de 3 pixels interne et une bordure externe de 3 pixels orange. Ainsi, il ne reste plus qu'un rayon jaune de (50-3=47 pixels) et une bordure externe de 6 pixels effectivement.

2 - Les ellipses avec ellipse

Et pour faire une ellipse ? C'est simple, il faut utiliser la balise ellipse.

Cette balise fonctionne comme cercle mais elle possède deux attributs rx et ry plutôt qu'un simple rayon.

03° Tester le code ci-dessous puis modifier les valeurs pour tenter d'obtenir le résultat ci-dessous.

<svg width="200" height= "100">

    <ellipse cx="50" cy="50" rx="40" ry="20" fill="green" />

    <ellipse cx="150" cy="50" rx="20" ry="40" fill="red" />

    <ellipse cx="50" cy="150" rx="10" ry="40" fill="orange" />

</svg>

Comme vous le voyez, les objets peuvent se superposer. La superposition se fait par défaut dans l'ordre de déclaration des formes.

04° Modifier l'ordre de déclaration des formes pour obtenir ceci :

3 - Les rectangles avec rect

Et bien, il s'agit de la balise XML rect.

Voici un exemple où nous utiliserons en plus une autre codification des couleurs, la codification rgb en décimal 0-255.

<svg width="400" height= "100">

    <rect width="300" height= "100" fill="rgb(100,100,200)" />

    <rect x="250" y="50" width="30" height="30" fill="rgb(200,200,100)" />

</svg>

Comme vous le voyez, on retrouve les mêmes attributs. Par défaut, x et y sont définis à 0. Il s'agit du coin supérieur gauche de votre rectangle.

05° Réaliser le dessin ci-dessous :

Vous savez maintenant faire des rectangles. Il vous reste à savoir les arrondir. Et pour cela, il faut utiliser la balise rect en définissant rx et ry qui contiennent le rayon de courbure des bords de votre rectangle. Plus cette valeur est grande, plus le bord est arrondi.

06° Tester le code ci-dessous :

<svg width="400" height= "100">

    <rect rx="10" ry="10" width="300" height= "100" fill="rgb(100,100,200)" />

    <rect x="250" y="50" width="30" height="30" fill="rgb(200,200,100)" />

</svg>

07° Illustrez une suite arithmétique de raison 2 en partant de 1 :

4- Les textes avec text

Bon, quitte à réaliser un document illustrant les séries, autant ajouter un texte pour permettre de donner un peu plus d'explications.

Et pour faire cela, on utilise la balise text.

Utilisons un exemple :

<svg width="400" height="200">

    <text x="10" y="20" fill="red">u0</text>

    <rect rx="10" ry="10" x="60" y="0" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="60" y="50" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="120" y="50" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="180" y="50" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="60" y= "100" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="120" y= "100" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="180" y= "100" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="240" y= "100" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="300" y= "100" width="30" height="30" fill="rgb(200,200,100)" />

</svg>

u0

08° Rajouter les termes u1 et u2 par exemple.

On peut faire encore un peu mieux : on peut écrire penché en utilisant transform="rotate()".

Par exemple :     <text x="10" y="20" fill="red" transform="rotate(45)">u0</text>

Je rajoute la position de l'ancien texte en gris.

u0 u0

Le problème, c'est que le texte n'est plus exactement où je veux. Par contre, l'angle est défini en degré. Attention : les angles positifs sont ceux du sens horaire contrairement à la norme mathématique.

Le centre de la rotation est ici le point (0,0). Le texte a donc subi sa rotation comme s'il était sur une tige reliant le point (0,0) et ses propres coordonnées.

Pour illustrer ceci, voici la rotation d'un carré par rapport à l'origine (le point bleu) sur plusieurs angles :

J'ai obtenu ceci avec le code suivant :

<svg width="200" height="200">

    <rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" transform="rotate(15)" />

    <rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" transform="rotate(30)" />

    <rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" transform="rotate(45)" />

    <rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" transform="rotate(60)" />

    <rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" transform="rotate(75)" />

</svg>

Remarquez donc bien que transform=rotate peut s'appliquer à tous les objets, pas seulement sur le texte !

Pour faire tourner un texte par rapport à d'autres coordonnées, il suffit de les indiquer derrière la valeur de l'angle : transform="rotate(15,200,30)" veut dire de faire tourner l'objet par rapport au point (x=200, y=30).

09° Modifier le code des cubes donné juste au dessus pour obtenir une rotation autour de (x=250,y=30).

Attention au signe de votre rotation. On notera (normalement) que si vos objets sont à l'extérieur de la zone du dessin, ils n'apparaissent pas intégralement.

Le deuxième cube possède le code suivant :<rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" transform="rotate(-15,250,30)" />.

Vous devriez obtenir une imagee du type (le point bleu symbolise l'axe de rotation passant par le point de coordonnées (250,30):

Si on revient à nos textes sur les suites, il faut donc les faire tourner au plus près de leurs centres.

10° Rajouter cette fois les textes en les faisant tourner correctement autour de leur centre respectif.

u0 u1 u2

5- Les transformations TRANSLATION, AGGRANDISSEMENT et DEFORMATION.

Nous venons de voir plusieurs balises d'objets SVG, plusieurs attributs des ballises dont une transformation : la rotation.

Néanmoins, nous pouvons également faire subir une translation aux objets.

Translation

Pour cela, il faut utiliser transform="translate(x,y)". Les coordonnées x et y ne sont pas les coordonnées finales de l'objet mais les déplacements à lui faire subir.

Voici un exemple :

<svg width="200" height= "100">

    <rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x= "100" y="0" width="30" height="30" fill="rgb(200,200,100)" transform="translate(50,0)" />

</svg>

Traduction : on crée deux cubes identiques (sauf que le second est rouge). On applique translate sur le deuxième : il bouge de +50px en x et +0 px en y.

Et cela donne :

11° Rajouter quelques cubes pour donner une impression d'accélération :

Modification d'échelle

Reste à voir le changement d'échelle. Il s'agit de transform="scale(k)".

En mathématiques, vous diriez homothétie.

k correspond au facteur d'agrandissement. k = 0,5 veut dire qu'on réduit à 50%. k = 1.6 veut dire qu'on multiple les dimensions par 1.6 : on augmente de 60%. Attention à ne pas utiliser la virgule mais bien le point.

<svg width="200" height= "100">

    <rect rx="10" ry="10" x="0" y="0" width="30" height="30" fill="rgb(200,200,100)" />

    <rect rx="10" ry="10" x="30" y="0" width="30" height="30" fill="red" transform="scale(2)" />

</svg>

Attention : on multiplie également les positions en x et y. Ainsi, le carré rouge est définie en (x=30;y=0) mais sera créé en (60,0) car le facteur multiplicatif est 2.

Attention : on multiplie également les positions en x et y. Ainsi, le carré rouge est définie en (x=10;y=0) mais sera créé en (20,0) car le facteur multiplicatif est 2.

Encore mieux : on peut définir des modifications d'échelles différentes en x et en y : transform="scale(2,3)" va agrandir par 2 en x et par 3 en y.

12° Utilisez donc scale sur l'une de vos propres créations.

Déformation

Dernière chose : les déformations selon l'axe x ( skewX(k) ) ou l'axe y ( skewY(k) ). Il s'agit d'étirer la forme dans une direction. Un dessin vaut mieux qu'un long discours.

Sans déformation :

En X avec : transform="skewX(20)" et transform="skewX(40)" : on fait subir une rotation de 20° et 40° aux droites verticales, les horizontales restent fixes.

En Y avec : transform="skewY(15)" et transform="translate(100,0) skewY(30)":

Association d'effets : vous remarquerez qu'on peut associer les effets dans la définition de transform. Ici, je tourne de 30° en Y puis je translate de 100 de façon à ce que la rotation soit bien par rapport au point supérieur gauche de mon carré (initialement en 0,0) :

<svg width="200" height="60">

    <rect x="0" y="0" width="30" height="30" fill="rgb(200,200,100)" transform="skewY(15)"/>

    <rect x="0" y="0" width="30" height="30" fill="red" transform="translate(100,0) skewY(30)"/>

</svg>

13° Utiliser les déformations sur certaines de vos images pour en comprendre l'influence.

6- Les lignes avec line

Il existe plusieurs façons de tracer toutes sortes de lignes. Il faut utiliser la balise <line> et lui attribuer un certain nombre d'attributs.

Voici un premier exemple :

<svg height="400" width= "100">

    <line x1="0" y1="0" x2="400" y2= "100" stroke="blue" stroke-width="3" />

</svg>

Le code devrait commencer à vous sembler plus ou moins clair :

Si vous voulez tracer une ligne brisée, il faut donc définir trois balises à la suite les unes des autres.

14° Utiliser ces nouvelles balises pour créer approximativement l'image suivante :

Là où ça commence à devenir interessant, c'est dans l'application des transformations.

La correction intégrale des questions se trouve plus bas.

Imaginons que nous voulions tracer ceci :

15° Tracer une zone de dessin de (200x200) et y tracer une ligne bleue entre (0,100) et (200,100).

Bien. Nous voudrions maintenant dessiner une seconde ligne identique mais simplement en rotation de 30° par rapport au point central du dessin (100,100).

16° Tracer la forme suivante :

On peut aller plus loin en modifiant par exemple le type de trait.

Vous connaissez déjà stroke et stroke-width.

Il nous reste à voir stroke-linecape pour gérer la façon dont on dessine les extrémités et stroke-dasharray pour faire des pointillés.

Et voici le tout en exemple avec "butt" par défaut et les extrémités arrondies ou rectangulaires :

Ce qui correspond au code suivant :

<svg height="120" width="600">

    <line x1="20" y1="10" x2="580" y2="10" stroke="blue" stroke-width="10" stroke-linecap="butt" />

    <line x1="20" y1="60" x2="580" y2="60" stroke="blue" width="10" stroke-linecap="round" />

    <line x1="20" y1="110" x2="580" y2="110" stroke="blue" stroke-width="10" stroke-linecap="square" />

</svg>

Et pour les pointillés, vous avez accès à une grande gamme de pointillés puisqu'ils sont configurables avec stroke-dasharray :

La synthaxe du motif est simple : on donne la taille du trait, la taille de l'espace, la taille du trait suivant ... et le programme recopie le motif.

Ces lignes sont obtenues avec le code suivant :

<svg height="220" width="600">

    <line x1="20" y1="10" x2="580" y2="10" stroke="blue" stroke-width="3" stroke-dasharray="5,5" />

    <line x1="20" y1="60" x2="580" y2="60" stroke="blue" stroke-width="3" stroke-dasharray="10,10" />

    <line x1="20" y1="110" x2="580" y2="110" stroke="blue" stroke-width="3" stroke-dasharray="5,10" />

    <line x1="20" y1="160" x2="580" y2="160" stroke="blue" stroke-width="3" stroke-dasharray="10,30" />

    <line x1="20" y1="210" x2="580" y2="210" stroke="blue" stroke-width="3" stroke-dasharray="20,10,5,5,5,10" />

</svg>

Retournons vers l'étoile. Voici le code de l'étoile réalisée avec les droites :

<svg height="200" width="200">

    <line x1="0" y1= "100" x2="200" y2= "100" stroke="blue" stroke-width="3" />

    <line x1="0" y1= "100" x2="200" y2= "100" stroke="blue" stroke-width="3" transform="rotate(30,100,100)" />

    <line x1="0" y1= "100" x2="200" y2= "100" stroke="blue" stroke-width="3" transform="rotate(60,100,100)" />

    <line x1="0" y1= "100" x2="200" y2= "100" stroke="blue" stroke-width="3" transform="rotate(90,100,100)" />

    <line x1="0" y1= "100" x2="200" y2= "100" stroke="blue" stroke-width="3" transform="rotate(120,100,100)" />

    <line x1="0" y1= "100" x2="200" y2= "100" stroke="blue" stroke-width="3" transform="rotate(150,100,100)" />

</svg>

17° Réaliser le dessin suivant :

7- Les balises g et defs

Pour l'instant, on peut dire que la déclaration d'images SVG est plus ou moins simple et proche de l'HTML. C'est normal puisque SBG et HTML partent de la même structure, le XML.

Mais c'est un peu répétitif. On doit souvent faire du copier-coller car les éléments ont les mêmes propriétés. Heureusement, on peut faire mieux.

Balises génériques g

La balise g va nous permettre de limiter le code répétitif. Toutes les balises contenues dans cette balise g utiliseront les propriétés de la balise les contenant. Un exemple vaut mieux qu'une longue explication :

<svg height="200" width="200">

    <g stroke="blue" stroke-width="3" stroke-dasharray="5,5" >

        <line x1="0" y1= "100" x2="200" y2= "100" />

        <line x1="0" y1= "100" x2="200" y2= "100" transform="rotate(30,100,100)" />

        <line x1="0" y1= "100" x2="200" y2= "100" transform="rotate(60,100,100)" />

        <line x1="0" y1= "100" x2="200" y2= "100" transform="rotate(90,100,100)" />

        <line x1="0" y1= "100" x2="200" y2= "100" transform="rotate(120,100,100)" />

        <line x1="0" y1= "100" x2="200" y2= "100" transform="rotate(150,100,100)" />

    </g>

</svg>

Et on obtient :

Bon, la balise g ne peut contenir que les éléments de présentation, pas les coordonnées mais on gagne déjà pas mal de caractères de code.

18° Tester le code et modifier par exemple la couleur pour vérifier qu'une seule modification affecte toutes les lignes dessinées.

Balises génériques identifiées

Avec cette balise, nous allons pouvoir aller encore plus loin. Nous allons pouvoir entièrement définir un élément, lui donner un nom et simplement afficher des clones.

Encore une fois, autant donner un exemple :

<svg height="200" width="200">

    <g id="ma_ligne">

        <line x1="0" y1= "100" x2="200" y2= "100" stroke="blue" stroke-width="3" stroke-dasharray="5,5" />

    </g>

    <use href="#ma_ligne" transform="rotate(30,100,100)" />

    <use href="#ma_ligne" transform="rotate(60,100,100)" />

    <use href="#ma_ligne" transform="rotate(90,100,100)" />

    <use href="#ma_ligne" transform="rotate(120,100,100)" />

    <use href="#ma_ligne" transform="rotate(150,100,100)" />

</svg>

Explications :

Et on obtient :

19° Rajouter des cercles aux extrémités de la ligne "ma_ligne" en les rajoutant dans la balise g. Vous devriez obtenir :

Attention : Comme tout identifiant, il ne doit apparâitre qu'une seule fois dans chaque page. L'identifiant d'une balise g doit permettre de l'identifier sans aucun doute.

Voici le code utilisé pour réaliser le dessin ci-dessus (j'ai modifié l'identifiant en "mon_motif" puisque le dessin apparaît sur la même page que le dessin précédent avec "ma_ligne" :

<svg height="200" width="200">

    <g id="mon_motif" stroke="blue">

        <line x1="0" y1= "100" x2="200" y2= "100" stroke-width="3" stroke-dasharray="5,5" />

        <circle cx="10" cy= "100" r="8" stroke-width="4" fill="yellow" />

        <circle cx="190" cy= "100" r="8" stroke-width="4" fill="yellow" />

    </g>

    <use href="mon_motif" transform="rotate(30,100,100)" />

    <use href="mon_motif" transform="rotate(60,100,100)" />

    <use href="mon_motif" transform="rotate(90,100,100)" />

    <use href="mon_motif" transform="rotate(120,100,100)" />

    <use href="mon_motif" transform="rotate(150,100,100)" />

</svg>

On peut faire encore encore mieux en intégrant une balise g dans une balise g ! Je fais par exemple définir entièrement une étoile et je vais ensuite déplacer l'ensemble avec un translate.

Exemple :

Ca devient un peu technique mais il suffit de lire cet exemple pour en comprendre le principe :

<svg height="400" width="600">

    <g id="mon_etoile" >

        <g id="mon_motif2" stroke="blue">

            <line x1="0" y1= "100" x2="200" y2= "100" stroke-width="3" stroke-dasharray="5,5" />

            <circle cx="10" cy= "100" r="8" stroke-width="4" fill="yellow" />

            <circle cx="190" cy= "100" r="8" stroke-width="4" fill="yellow" />

        </g>

        <use href="#mon_motif2" transform="rotate(30,100,100)" />

        <use href="#mon_motif2" transform="rotate(60,100,100)" />

        <use href="#mon_motif2" transform="rotate(90,100,100)" />

        <use href="#mon_motif2" transform="rotate(120,100,100)" />

        <use href="#mon_motif2" transform="rotate(150,100,100)" />

    </g>

    <use href="#mon_etoile" transform="translate(250,0)" />

    <use href="#mon_etoile" transform="translate(125,200)" />

</svg>

En gros :

Vous pouvez tester ce code mais surtout il va falloir le comprendre car nous allons le reutiliser en partie avec les balises defs.

20° Rajouter quelques étoiles. N'oubliez de modifier les dimensions de votre objet svg au besoin.

La balise defs

Juste au dessus, on a réussi à définir une image dans une balise g nommée et à la réutiliser plusieurs fois. Mais, elle s'affiche dès sa création.

On peut faire un peu mieux : on peut définir une image dans une balise defs et cette fois ci, l'image ne va pas s'afficher tout de suite. On pourra l'utiliser à l'aide de son nom mais elle ne s'affichera pas dès sa déclaration.

L"intêret peut vous paraitre limité mais

Voici l'exemple basique d'utilisation :

<svg height="400" width="600">

    <defs>

        <g id="mon_motif3">

            <line x1="0" y1= "100" x2="200" y2= "100" stroke-width="3" stroke-dasharray="5,5" />

            <circle cx="10" cy= "100" r="8" stroke-width="4" fill="yellow" />

            <circle cx="190" cy= "100" r="8" stroke-width="4" fill="yellow" />

        </g>

        <g id="mon_etoile3" stroke="blue">

            <use href="#mon_motif3" />

            <use href="#mon_motif3" transform="rotate(30,100,100)" />

            <use href="#mon_motif3" transform="rotate(60,100,100)" />

            <use href="#mon_motif3" transform="rotate(90,100,100)" />

            <use href="#mon_motif3" transform="rotate(120,100,100)" />

            <use href="#mon_motif3" transform="rotate(150,100,100)" />

        </g>

    </defs>

    <use href="#mon_etoile3" transform="translate(250,0)" />

    <use href="#mon_etoile3" transform="translate(125,200)" />

</svg>

Explications :

Heureusement, ce n'est pas le seul intêret : nous allons surtout pouvoir ne pas déclarer certains attributs fondamentaux lors de la déclaration de l'objet. Comme la couleur par exemple.

21° Suivre les instructions qui devraient vous permettre de réaliser le dessin ci-dessous :

Correction possible (attention, il faudra garder votre déclaration de l'objet "mon_motif3" issu de l'image précédente) :

<svg height="400" width="600">

    <defs>

        <g id="mon_etoile4"">

            <use href="#mon_motif3" />

            <use href="#mon_motif3" transform="rotate(30,100,100)" />

            <use href="#mon_motif3" transform="rotate(60,100,100)" />

            <use href="#mon_motif3" transform="rotate(90,100,100)" />

            <use href="#mon_motif3" transform="rotate(120,100,100)" />

            <use href="#mon_motif3" transform="rotate(150,100,100)" />

        </g>

    </defs>

    <use href="#mon_etoile4" stroke="blue" />

    <use href="#mon_etoile4" transform="translate(250,0)" stroke="orange" />

    <use href="#mon_etoile4" transform="translate(125,200)" stroke="red" />

</svg>

Voilà. C'est tout pour aujourd'hui pour cette introduction.

Dans les activités suivantes SVG, nous verrons d'autres objets (les lignes notamment) puis les animations.

Avant la norme SVG2, en SVG1, il fallait noter ceci pour utiliser les liaisons entre balises :

<use xlink:href="#mon_motif" transform="rotate(30,100,100)" />

Si vous voyez des codes avec ce fameux xlink:, c'est que le code a été créé initialement avec SVG version 1.