Aller au contenu

Découvrir le SVG/Manipulations avancées

Un livre de Wikilivres.

Réutilisation d'objets

[modifier | modifier le wikicode]

Un objet peut être réutilisé, « cloné ». Il faut pour cela lui définir un attribut id (identité), c'est-à-dire lui donner un nom, une étiquette. On peut ensuite utiliser un élément use et faire référence à cet objet grâce à l'attribut href de l'espace de nom xlink.

L'exemple ci-dessous dessine un rectangle, puis en fait une copie située 60 px plus à droite.

 Les attributs x et y sont des coordonnées relatives à l'objet original.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="106" height="71" version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
>

  <title> Copie d'un rectangle </title>
  <desc> Deux rectangles identiques </desc>

  <rect
    x="0" y="0" width="106" height="71"
    stroke="black" fill="none"
  /> <!-- Cadre de l'image -->

  <rect id="rectangle1"
    x="18" y="18" width="36" height="18"
  /> <!-- Rectangle de base -->

  <use xlink:href="#rectangle1" x="60" /> <!-- Copie du rectangle à une abscisse différente -->
</svg>

On peut définir un objet sans le tracer pour ensuite le dupliquer. Cela se fait avec l'élément defs, qui s'utilise comme l'élément g. Les éléments defs devraient se trouver juste après la balise d'ouverture <svg … >. L'exemple suivant donne le même résultat que ci-dessus :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="106" height="71" version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
>

  <title> Copie d'un rectangle </title>
  <desc> Deux rectangles identiques </desc>

  <defs>
    <rect id="rectangle1"
      width="36" height="18"
    /> <!-- Rectangle de base -->
  </defs>

  <rect
    x="0" y="0" width="106" height="71"
    stroke="black" fill="none"
  /> <!-- Cadre de l'image -->

  <use xlink:href="#rectangle1" x="18" y="18" /> <!-- Première copie du rectangle -->
  <use xlink:href="#rectangle1" x="71" y="18" /> <!-- Seconde copie du rectangle -->
</svg>

Ici, l'objet original a été défini à l'origine (0, 0), les attributs x et y de l'élément use deviennent donc des coordonnées absolues.

À la place de l'élément defs, on peut utiliser l'élément symbol qui fonctionne de la même manière. Les deux différences sont que :

  • l'identifiant se met directement dans la balise, <symbol id="…"> … </symbol> ;
  • lorsque l'on utilise un élément symbol, on crée une fenêtre (viewport) à l'intérieur de l'image ; on peut par exemple utiliser les attributs preserveAspectRatio et viewBox.

De nombreux logiciels de dessin utilisent la notion de « calque » (layer). Un calque est un groupe de figures qui sont ensemble. Il faut imaginer un document comme une superposition de feuilles transparentes, chaque feuille transparente étant un calque. On peut typiquement changer l'ordre d'empilement des calques, certains dessins en cachant d'autres, et l'on peut rendre visible ou invisible un calque (par exemple afficher une grille ou la masquer).

En SVG, il n'y a pas de notion de calque, mais la notion de groupe (élément g) et de symbole (éléments symbol) sont équivalentes.

L'ordre des instructions dans le document indique l'ordre dans lequel les éléments sont dessinés ; ainsi, si l'on dessine deux éléments, le deuxième peut recouvrir le premier, le cacher. Ainsi, l'ordre des groupe correspond à l'ordre des calques, le premier groupe du document est le calque du bas et le dernier groupe est le calque du dessus. On peut changer l'ordre des calques en déplaçant les groupes dans le fichier.

Par ailleurs, un groupe peut posséder un attribut visibility qui permet de le masquer (valeur "hidden") ou de l'afficher (valeur "visible"). S'il s'agit d'un symbole ou d'un groupe mis dans un élément defs, l'attribut doit avoir la valeur "inherit" afin que s'applique la valeur définie dans l'appel use, par exemple :

  <symbol
      id="rectangle1" visibility="inherit"
  >
    <rect 
      width="36" height="18"
    /> <!-- Rectangle de base -->
  </symbol>

  <use
    visibility="visible"
    xlink:href="#rectangle1" x="18" y="18"
  />
</svg>

Transformations géométriques

[modifier | modifier le wikicode]

Attribut transform

[modifier | modifier le wikicode]

Nous avons déjà présenté l'attribut transform précédemment, voir Éléments graphiques > Syntaxe générale et aspect des objets.Nous disposons également des transformations suivantes (les virgules peuvent être omises) :

  • rotate(angle, cx, cy) : effectue une rotation de centre (cx, cy), les valeurs étant dans l'unité par défaut, et d'amplitude angle (en degrés par défaut) ;
  • translate(tx, ty) : effectue une translation de vecteur (tx, ty) ;
  • scale(s) : effectue une homothétie (changement d'échelle) de facteur s ;
  • scale(sx, sy) : dilate d'un facteur sx selon l'axe des x et d'un facteur sy selon l'axe y ;
  • skewX(angle) : incline l'image d'une quantité angle (en degrés par défaut) selon l'axe des x ;
  • skewY(angle) : incline l'image d'une quantité angle (en degrés par défaut) selon l'axe des y ;
  • matrix(a, b, c, d, e, f) : effectue l'application linéaire correspondant à la matrice de transformation .

Pour reprendre l'exemple ci-dessus, on pourrait écrire :

 <use xlink:href="#rectangle1"
   transform="scale(2) rotate(45) translate(18, 18)" />

Concernant la transformation matricielle, si (x0, y0) sont les coordonnées avant transformation et (x1, y1) sont les coordonnées après transformation, on a :

.

On a donc les équivalences :

Logo

Quand une série de transformations est spécifiée, celles-ci sont appliquées de droite à gauche.

<circle r="100" transform="translate(18, 18) scale(2) " />

La séquence équivaut à l'arborescence ci-dessous : les éléments internes étant appliqués avant les éléments englobants.

<g transform="translate(18, 18)"> <!-- en troisième -->
  <g transform="scale(2)"> <!-- en deuxième -->
    <circle r="100" /> <!-- Interne en premier -->
  </g>
</g>

Exemple : création d'une courbe de Koch

[modifier | modifier le wikicode]
Courbe de Koch de profondeur 6.
Principe du tracé d'une courbe de von Koch en SVG.

La courbe de Koch est une courbe fractale qui peut se construire en répétant des opérations simples. Le code suivant a été proposé par User:Fibonacci sur Wikimedia Commons. Il consiste à tracer un trait horizontal de longueur arbitraire l0 = 14 et de lui attribuer l'étiquette it0 :

<line x2="14" stroke="#000" stroke-width="10" stroke-linecap="round" id="it0"/>

On remarque ici que l'on a par défaut x1 = 0, y1 = 0, y2 = 0.

Cet objet est ensuite translaté de cette même longueur l0 = 14 puis tourné de –60 ° ; le tout est mis dans un groupe portant l'identifiant it1 :

<g id="it1">
  <line x2="14" stroke="#000" stroke-width="10" stroke-linecap="round" id="it0"/>
  <use xlink:href="#it0" transform="translate(14)rotate(-60)"/>
</g>

Cet objet it1 est à son tour dupliqué, translaté d'une longueur 3 × l0 = 42 et retourné horizontalement par la commande scale(-1, 1). Le tout est mis dans un groupe portant l'identifiant it2. Et ainsi de suite ; comme on a six étapes récursives, la dernière translation se fait d'une longueur 36 × l0 = 10 206. L'ensemble est ensuite ramené à une échelle permettant de tenir dans la fenêtre de 621 × 180. Le code complet est donc :

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="621" height="180">

<g transform="translate(4,179)scale(0.06)">
  <g id="itB">
    <g id="itA">
      <g id="it9">
        <g id="it8">
          <g id="it7">
            <g id="it6">
              <g id="it5">
                <g id="it4">
                  <g id="it3">
                    <g id="it2">
                      <g id="it1">
                        <line x2="14" stroke="#000" stroke-width="10" stroke-linecap="round" id="it0"/>
                        <use xlink:href="#it0" transform="translate(14)rotate(-60)"/>
                      </g>
                      <use xlink:href="#it1" transform="translate(42)scale(-1,1)"/>
                    </g>
                    <use xlink:href="#it2" transform="translate(42)rotate(-60)"/>
                  </g>
                  <use xlink:href="#it3" transform="translate(126)scale(-1,1)"/>
                </g>
                <use xlink:href="#it4" transform="translate(126)rotate(-60)"/>
              </g>
              <use xlink:href="#it5" transform="translate(378)scale(-1,1)"/>
            </g>
            <use xlink:href="#it6" transform="translate(378)rotate(-60)"/>
          </g>
          <use xlink:href="#it7" transform="translate(1134)scale(-1,1)"/>
        </g>
        <use xlink:href="#it8" transform="translate(1134)rotate(-60)"/>
      </g>
      <use xlink:href="#it9" transform="translate(3402)scale(-1,1)"/>
    </g>
    <use xlink:href="#itA" transform="translate(3402)rotate(-60)"/>
  </g>
  <use xlink:href="#itB" transform="translate(10206)scale(-1,1)"/>
</g>
</svg>

Fenêtre (viewport)

[modifier | modifier le wikicode]

Certains éléments créent une fenêtre (viewport) : svg (crée la fenêtre cadre), symbol (voir ci-dessus), image et foreignObject.

Les limites de cette fenêtre peuvent être définis, comme indiqué précédemment, par les attributs x, y, width et height (voir Structure d'un fichier SVG > Les attributs de l'élément svg). Cela permet de translater l'objet et le cas échéant de lui appliquer un facteur d'échelle, en fonction de la valeur de l'attribut preserveAspectRatio (ibid.).

L'attribut viewBox permet de définir un repère à l'intérieur de cette fenêtre : la syntaxe

viewBox="xmin, ymin, largeur, hauteur"

indique que le point en haut à gauche aura les coordonnées (xmin, ymin) et que le point en bas à droite les coordonnées (xmin + largeur, ymin + hauteur). Notez que les virgules ne sont pas obligatoires.

Ainsi, nous reprenons l'exemple ci-dessous mais en utilisant l'attribut viewBox pour avoir des valeurs de coordonnées et de longueur en centimètres plutôt qu'en pixels. Notez qu'il faut redéfinir l'épaisseur de trait par défaut (nous prenons ici une épaisseur unité de 0,03 cm).

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="3cm" height="2cm" version="1.1"
     viewBox="0 0 3 2"
     stroke-width="0.03"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
>

  <title> Copie d'un rectangle </title>
  <desc> Deux rectangles identiques </desc>

  <defs>
    <rect id="rectangle1"
      width="1" height="0.5"
    /> <!-- Rectangle de base -->
  </defs>

  <rect
    x="0" y="0" width="3" height="2"
    stroke="black" fill="none"
  /> <!-- Cadre de l'image -->

  <rect
    x="0" y="0" width="3" height="2"
    stroke="black" fill="none"
  /> <!-- Cadre de l'image -->

  <use xlink:href="#rectangle1" x="0.5" y="0.5" /> 
  <use xlink:href="#rectangle1" x="2" y="0.5" />
</svg>

Apparence des éléments

[modifier | modifier le wikicode]

Un marqueur est un symbole graphique qui s'affiche au milieu ou à l'extrémité d'une ligne : triangle (pointe de flèche), carré, disque… On peut ainsi créer un élément marker et l'utiliser dans un élément path, line, polyline ou polygon.

L'élément marker est un « conteneur », à l'image d'un élément g, qui possède un identifiant (attribut id). Lorsque l'on dessine la courbe (donc dans l'élément path, line…), on place alors un attribut marker-start (marqueur en début de ligne), marker-mid (milieu) ou marker-end (marqueur en fin de ligne) avec la valeur "url(#identifiant)".

Par exemple, si l'on désire mettre un disque à chaque extrémité de la ligne, on peut écrire :

<defs>
  <marker
      id="extremiteDeLigne"
  >
    <circle
      cx="1.5" cy="1.5" r="1"
      stroke="none" fill="blue"
    />
  </marker>
</defs>

<path
  d="M10 50
  Q50 10, 75 50"
  marker-start="url(#extremiteDeLigne)"
  marker-end="url(#extremiteDeLigne)"
  stroke="black" stroke-width="5" fill="none"
/>

mais le résultat obtenu n'est probablement pas celui attendu :

  • le disque n'est pas centré sur l'extrémité de la ligne mais est décalé ;
  • le disque est très petit et si vous augmentez le rayon, vous obtenez un carré à la place.

En effet, le marqueur est affiché dans une fenêtre (viewport) dont la taille est proportionnelle à la largeur du trait de la courbe (ici 5 px) et de dimension 3 × 3 par défaut (c'est-à-dire un carré faisant trois fois l'épaisseur de la ligne).

Le code suivant est plus satisfaisant :

<marker
    id="extremiteDeLigne"
    markerWidth="5" markerHeight="5"
    refX="2.5" refY="2.5"
>
  <circle
    cx="2.5" cy="2.5" r="2.5"
    stroke="none" fill="blue"
  />
</marker>

Les attributs :

  • markerWidth et markerHeight définissent une fenêtre de 5 × 5 (par rapport à l'épaisseur du trait) ;
  • refX et refY décalent la fenêtre de ses demi-dimensions afin qu'elle soit centrée sur l'extrémité de la ligne.

Le cercle est ensuite placé au centre de la fenêtre et son rayon est choisi pour qu'il soit inscrit dans la fenêtre ; si l'on trace le périmètre (on définit une couleur par le paramètre stroke), il faut ajuster le rayon pour que l'épaisseur du trait soit contenue dans la fenêtre.

Le code suivant permet de placer des traits d'arrêt perpendiculaires à la ligne :

<defs>
  <marker
      id="extremiteDeLigne"
      markerWidth="1" markerHeight="10"
      refX="0.5" refY="5"
      orient="auto"
  >
    <line
      x1="0.5" y1="0" x2="0.5" y2="10"
      stroke="black" fill="none"
    />
  </marker>
</defs>

<path
  d="M10 50
  Q50 10, 75 50"
  marker-start="url(#extremiteDeLigne)"
  marker-mid="url(#extremiteDeLigne)"
  marker-end="url(#extremiteDeLigne)"
  stroke="black" stroke-width="1" fill="none"
/>

Nous avons utilisé l'attribut orient="auto" qui permet d'aligner les axes du repère de la fenêtre du marqueur avec la direction locale de la ligne. On peut à la place indiquer une valeur numérique, il s'agit alors de l'angle duquel est tournée la fenêtre par rapport au la page (et non pas par rapport à la direction de la courbe).

 Pour être sûr que le marquer d'origine ne soit pas dessiné, il doit avoir l'attribut display="none" ; c'est le cas s'il est placé dans l'élément defs.

Voici un exemple complet :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="29.7cm" height="21cm" version="1.1"
     viewBox="0 0 297 210"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

  <title> Cote d'angle </title>
  <desc> Cote d'angle </desc>

  <defs>
      polygon.fleche {
        stroke: none;
        fill:black
      }
      path {
        stroke: black;
        stroke-width: 0.199;
        fill:none
      }
      text {
        font-family: "Liberation Sans", "Nimbus Sans L", Arial, sans-serif
      }
    ]]></style>

    <marker
      id="fleche1"
      markerWidth="10" markerHeight="6.67"
      refX="0" refY="3.33"
      orient="auto"
    >
      <polygon class="fleche"
        points="0 3.33, 10 0, 5 3.33, 10 6.67"
      />
    </marker>

    <marker
      id="fleche2"
      markerWidth="10" markerHeight="6.67"
      refX="10" refY="3.33"
      orient="auto"
    >
      <polygon class="fleche"
        points="10 3.33, 0 0, 5 3.33, 0 6.67"
      />
    </marker>
  </defs>

    <!-- cote d'angle -->

    <path
      d="M259.75 182.63
         A6 6
         0, 0, 0
         259.75 176.63"
         marker-start="url(#fleche1)"
         marker-end="url(#fleche2)"
    />

    <text
      x="261.44" y="180.89"
      font-size="2.7"
      text-anchor="start"
    >
      60°
    </text>

 </g>

</svg>

Ce code est un extrait de l'image Fichier:Trame isometrique.svg.

Les différents objets graphiques peuvent posséder un attribut fill-opacity dont la valeur peut être :

  • un nombre entre 0 et 1 : fill-opacity="0" indique un élément totalement transparent, fill-opacity="1" indique un élément totalement opaque (valeur par défaut) ;
  • la valeur fill-opacity="inherit" : typiquement pour un objet « cloné » par un élément use, utilise l'opacité définie dans l'élémznt use.

Dégradés de couleurs

[modifier | modifier le wikicode]

En SVG, on peut définir deux types de dégradés de couleur : les dégradés linéaires — la couleur change lorsque l'on se déplace dans une direction — et les dégradés radiaux — la couleur change lorsque l'on s'éloigne d'un point.

Un dégradé est représenté par un identifiant. Il peut être appliqué pour le remplissage d'un objet, avec la syntaxe fill="url(#identifiant)", ou à son trait avec la syntaxe stroke="url(#identifiant)".

Le dégradé peut se représenter comme une échelle de couleurs. Les couleurs de référence sont appelées « arrêts » (stops) et sont caractérisés par :

  • leur position sur l'échelle (offset) ;
  • la nature de la couleur.

Ainsi, les gradients contiennent au moins deux éléments stop ayant pour attributs :

  • offset : nombre entre 0 et 1, ou bien pourcentage, désignant la position dans l'échelle ; le bas de l'échelle est désigné par offset="0" ou bien offset="0%", le haut de l'échelle est désigné par offset="1" ou bien offset="100%" ;
  • stop-color : couleur habituelle, par exemple stop-color="black" ou bien stop-color="#000000" (voir Éléments graphiques > Syntaxe générale et aspect des objets) ;
  • le cas échéant stop-opacity qui définit l'opacité de l'arrêt (voir ci-dessus).

Dégradé linéaire

[modifier | modifier le wikicode]

Un dégradé linéaire est défini par un élément linearGradient. Cet élément est entre les balises defs en début de document est possède un identifiant (attribut id). L'exemple suivant définit un dégradé du bleu au rouge et l'applique à un rectangle :

<defs>
  <linearGradient
    id="dégradé"
  >
    <stop offset="0" stop-color="blue" />
    <stop offset="1" stop-color="red" />
  </linearGradient>
</defs>

<rect id="rectangle1"
    x="18" y="18" width="36" height="18"
    fill="url(#dégradé)"
/>

On peut également définir le vecteur du gradient sous la forme de quatre attributs x1, y1, x2 et y2 : les arrêts à 0 % et à 100 % sont placés respectivement aux points P1(x1, y1) et P2(x2, y2), et les ligne de même couleur sont perpendiculaires à la droite (P1P2). Par exemple, le code suivant fait un dégradé suivant la grande diagonale du rectangle :

<defs>
  <linearGradient
    id="dégradé"
    x1="0" y1="0"
    x2="100%" y2="100%"
  >
    <stop offset="0" stop-color="blue" />
    <stop offset="1" stop-color="red" />
  </linearGradient>
</defs>

<rect id="rectangle1"
    x="18" y="18" width="36" height="18"
    fill="url(#dégradé)"
/>

L'élément peut contenir un attribut gradientTransform qui fonctionne de la même manière que l'attribut transform des objets graphiques (voir ci-dessus). Cela permet par exemple d'incliner (skew) le dégradé.

Enfin, l'attribut spreadMethod définit ce qui se passe si l'objet est plus étendu que le dégradé (c'est-à-dire si le vecteur gradient ne couvre pas les abscisses et les ordonnées de 0 à 100 % de l'objet) :

  • spreadMethod="pad" : les couleurs aux extrêmes sont étendues jusqu'aux bords de l'objet ;
  • spreadMethod="reflect" : le dégradé part dans l'autre sens ;
  • spreadMethod="repeat" : le dégradé recommence, il se répète.

Dégradé radial

[modifier | modifier le wikicode]

Un dégradé radial s'obtient avec l'élément radialGradient. Les attributs spécifiques sont :

  • cx, cy et r : paramètre du disque contenant le dégradé ; l'arrêt à 100 % se situe sur le périmètre du cercle de centre (cx, cy) et de rayon r ; par défaut, le disque est le plus petit disque contenant l'objet (c'est-à-dire que cx = cy = r = 50 %) ;
  • fx, fy : coordonnées du foyer du dégradé ; l'arrêt à 0 % se situe au point de coordonnées (fx, fy) ; par défaut, ce point se situe au centre du disque (fx = cx, fy = cy).

On dispose également des attributs gradientTransform et spreadMethod.

Par exemple :

<defs>
  <radialGradient
    id="dégradé"
  >
    <stop offset="0" stop-color="blue" />
    <stop offset="1" stop-color="red" />
  </radialGradient>
</defs>

<rect
    x="10%" y="10%" width="80%" height="80%"
    fill="url(#dégradé)" stroke-width="3"
/>

Il est possible de remplir une surface par un motif.

Un motif est un dessin inclus entre les balises d'un élément pattern. Il s'utilise de la même manière qu'un dégradé.

Par exemple, si l'on veut remplir une surface par des disques bleus :

<defs>
  <pattern
    id="motif"
    x="0" y="0" width="0.1" height="0.1"
  >
    <circle
      cx="5" cy="5" r="3"
      fill="blue" stroke="none"
    />
  </pattern>
</defs>

<rect
    x="10%" y="10%" width="80%" height="80%"
    fill="url(#motif)" stroke="black" stroke-width="1"
/>

Les paramètres width et height demandent quelques explications. Par défaut, la valeur 1 désigne la dimension totale de l'objet à remplir (largeur totale pour width, hauteur totale pour height). En mettant les valeurs 0.1, nous indiquons que le motif est répété tous les 0,1 dans l'unité locale, c'est-à-dire tous les 1/10 de la largeur et de la hauteur ; cela affiche donc 10 motif dans le sens de la hauteur et 10 motifs dans le sens de la largeur, soit 100 disque sur la surface.

Cette situation peut poser problème : en effet, la taille et les proportions largeur/hauteur du motif dépendent des dimensions de l'objet alors que l'on voudra sans doute que le motif apparaisse tel que dessiné.

On peut indiquer des dimensions « classiques » avec l'attribut patternUnits="userSpaceOnUse" : les valeurs indiquées dans les attributs width et height sont alors la largeur et la hauteur du rectangle dans lequel le motif est dessiné, et la surface est ensuite pavée par ces rectangles. Les dimensins du motif sont alors indépendantes des dimensions de l'objet. Par exemple :

<defs>
  <pattern
    id="motif"
    patternUnits="userSpaceOnUse"
    x="7.5" y="7.5" width="15" height="15"
  >
    <circle
      cx="5" cy="5" r="3"
      fill="blue" stroke="none"
    />
  </pattern>
</defs>

<rect
    x="10%" y="10%" width="80%" height="80%"
    fill="url(#motif)" stroke="black" stroke-width="1"
/>

Les motifs s'appliquent également aux contours.

Voir aussi : commons:Category:SVG patterns.

Traits et pointillés

[modifier | modifier le wikicode]

Les éléments à une dimension — chemins (path), segments de droite (line), polygones (polyline) — disposent d'un paramètre stroke-dasharray. Il s'ensuit une liste de nombres séparés par des virgules, qui correspondent à la longueur des segments et des espaces vides. Les nombres peuvent être des longueurs — avec une unité (mm, in, px) ou sans unité pour l'unité par défaut — ou bien des pourcentages — % —, il s'agit alors du pourcentage de la taille de l'image ou de la boîte englobante (dégradé, motif, masque, filtre).

Exemple

Pour un trait mixte (alternance trait long-trait court) :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<!-- taille visée : format A4 (21 cm × 29,7 cm)
  avec 90 dpi, 1cm = 35.43px (arrondi à l'entier le plus proche) -->

<svg width="744" height="1052" version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     font-family="monospace" font-size="12"
>

  <line
    x1="0" y1="0" x2="200" y2="200"
    stroke="black" stroke-width="1"
    stroke-dasharray = "40, 8, 8, 8"
  />
</svg>

Le langage SVG dispose d'éléments permettant des faire des animations[1],[2], essentiellement les éléments animate et animateTransform. Il faut pour cela que le navigateur gère ces éléments ; c'est le cas de d'Opera, Firefox, Safari et Chrome.

Les éléments graphiques sont définis par des paramètres numériques (position, taille…). L'élément animate permet de modifier les valeurs de manière continue durant une certaine durée. La syntaxe globale est :

<animate attributeName="paramètre"
     begin="instantInitial" dur="durée"
     from="valeurInitiale" to="valeurFinale"
/>

Elle concerne son parent direct. Par exemple, si l'on veut changer la position d'un rectangle, on écrit :

<rect x="0" y="0" width="5" height="5" stroke="black" stroke-width="1px" fill="none">
  <animate attributeName="x"
      begin="0s" dur="5s"
      from="0" to="10"
 />
</rect>

le rectangle va ainsi passer de la position x = 0 à x = 10 en cinq secondes. Vous remarquerez que la balise rect a été coupée en deux : <rect…> … </rect…> au lieu de la balise unique <rect… /> habituelle.

Dans l'élément animate, l'attribut fill indique le comportement lorsque l'animation touche à sa fin : "freeze" pour que l'objet reste dans son état final, "remove" pour qu'il revienne à son état initial.

Si l'on veut modifier un paramètre de l'attribut transform, on utilise l'élément animateTransform.

Exemple complet :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="320px" height="200px" version="1.1"
     viewBox="0 0 320 200"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

  <title> Ça bouge ! </title>
  <desc> Texte se modifiant de plusieurs manières </desc>

  <defs>
    <style type="text/css"><![CDATA[
      text {
        font-family: "Liberation Serif", "Times New Roman", serif;
        font-size: 20
      }
    ]]></style>
  </defs>

  <!-- le texte bouge de droite à gauche -->
  <text x="0" y="15">
    <animate attributeName="x"
      begin="0s" dur="5s"
      fill="freeze"
      from="200" to="0"
    />
    Ça bouge !
  </text>

  <!-- le texte passe du bleu au rouge -->
  <text x="0" y="35">
    <animate attributeName="fill"
      begin="0s" dur="5s"
      fill="freeze"
      from="#0000ff" to="#ff0000"
    />
    Ça bouge !
  </text>

  <!-- le texte grossit -->
  <text x="0" y="55">
    <animate attributeName="font-size"
      begin="0s" dur="5s"
      fill="freeze"
      from="1" to="16"
    />
    Ça bouge !
  </text>

  <!-- le texte tourne -->
  <g transform="translate(120, 35)">
    <text x="0" y="0" text-anchor="middle">
      <animateTransform attributeName="transform"
        type="rotate"
        begin="0s" dur="5s"
        fill="freeze"
        from="0" to="360"
      />
      Ça bouge !
    </text>
  </g>

</svg>

Voir le résultat.

Plutôt que de mettre l'élément animate entre les balises ouvrantes et fermantes de l'élément graphique, on peut aussi y faire référence avec un attribut xlink:href, par exemple :

<rect id="rectangle"
  x="0" y="0" width="5" height="5" stroke="black" stroke-width="1px" fill="none"
/>
<animate xlink:href="#rectangle"
  attributeName="x"
  begin="0s" dur="5s"
  from="0" to="10"
/>

Utilisation de styles

[modifier | modifier le wikicode]

Les styles permettent de définir des paramètres par défaut. Lorsque plusieurs objets utilisent les mêmes paramètres (couleur de remplissage, couleur de trait, épaisseur de trait…), il est utile de définir un style. Ainsi, lorsque l'o change le style, cela change l'affichage pour tous les objets, donc :

  • cela permet des changement faciles et rapide même lorsqu'il y a de nombreux objets ;
  • cela assure une homogénéité au sein du document voire entre les documents (dans le cas d'un feuille de style extérieure) ;
  • cela évite les erreurs : une erreur affectant plusieurs objets, elle est repérée beaucoup plus vite.

Style au format CSS

[modifier | modifier le wikicode]
Pour plus de détails voir : Le langage CSS.

Feuille de style externe

[modifier | modifier le wikicode]

On peut avoir recours à une feuille de style externe, sous la forme d'un fichier .css. Par exemple

Fichier monstyle.css

rect {
  fill: red;
  stroke: blue;
  stroke-width: 3
}

Fichier mondessin.svg

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="monstyle.css" type="text/css"?>

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

<svg width="3cm" height="2cm" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

  <title> Rectangle </title>
  <desc> Un rectangle </desc>

  <rect
    x="0.5cm" y="0.5cm" width="2cm" height="1cm"
  />

</svg>

Dans le fichier CSS, nous définissons le style par défaut des éléments rect.

Dans le fichier SVG, nous avons ajouté une référence à la feuille de style : <?xml-stylesheet href="mystyle.css" type="text/css"?>.

Styles définis dans le fichier SVG

[modifier | modifier le wikicode]

Les styles peuvent être déclarés à l'intérieur du fichier SVG, soit en en-tête, soit dans l'élément lui-même — mais alors le CSS présente peu d'intérêt.

En en-tête du fichier

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

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

<svg width="3cm" height="2cm" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

  <title> Rectangle </title>
  <desc> Un rectangle </desc>

  <defs>
    <style type="text/css"><![CDATA[
      rect {
        fill: red;
        stroke: blue;
        stroke-width: 3
      }
    ]]></style>
  </defs>

  <rect
    x="0.5cm" y="0.5cm" width="2cm" height="1cm"
  />
</svg>

Dans l'élément

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

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

<svg width="3cm" height="2cm" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

  <title> Rectangle </title>
  <desc> Un rectangle </desc>

  <rect
    x="0.5cm" y="0.5cm" width="2cm" height="1cm"
    style="fill: red; stroke: blue; stroke-width: 3"
  />
</svg>

On peut définir des classes, c'est-à-dire des styles différenciés. Par exemple :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

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

<svg width="3cm" height="4cm" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

  <title> Rectangle </title>
  <desc> Un rectangle </desc>

  <defs>
    <style type="text/css"><![CDATA[
      rect {
        stroke-width: 3
      }
      rect.rougebleu {
        fill: red;
        stroke: blue;
      }
      rect.vertjaune {
        fill: green;
        stroke: yellow;
      }
    ]]></style>
  </defs>

  <rect class="rougebleu"
    x="0.5cm" y="0.5cm" width="2cm" height="1cm"
  />
  <rect class="vertjaune"
    x="0.5cm" y="2cm" width="2cm" height="1cm"
  />
</svg>

ou encore :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

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

<svg width="3cm" height="4cm" version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

  <title> Rectangle </title>
  <desc> Un rectangle </desc>

  <defs>
    <style type="text/css"><![CDATA[
      rect {
        stroke-width: 3
      }
      use.rougebleu {
        fill: red;
        stroke: blue;
      }
      use.vertjaune {
        fill: green;
        stroke: yellow;
      }
    ]]></style>

    <rect id="modele"
        width="2cm" height="1cm"
    />
  </defs>

  <use xlink:href="#modele"
    class="rougebleu"
    x="0.5cm" y="0.5cm"
  />
  <use xlink:href="#modele"
    class="vertjaune"
    x="0.5cm" y="2cm"
  />
</svg>

Passage de la souris

[modifier | modifier le wikicode]

L'exemple suivant permet de modifier l'apparence d'objets lorsque le pointeur de la souris survole l'objet (hover)[3].

Fichier SVG :

<svg width="150" height="150" viewBox="0 0 100 100">
  <g class="highlight">
    <g>
      <circle cx="50" cy="50" r="40" />
      <text x="50" y="60" text-anchor="middle" fill="#FFF">Hi!</text>
    </g>
  </g>
</svg>

Fichier CSS :

text {
  fill: #FFF;
  font: bold 30px sans-serif;
  stroke-width: 0;
}

.highlight {
  stroke: #0F0;
  stroke-width: 0;
  transition: stroke-width 300ms;
}

.highlight:hover {
  stroke-width: 10px;
}

.highlight:hover text {
  stroke-width: 1px;
}

Style au format XSL

[modifier | modifier le wikicode]

Le XSL est un langage permettant de transformer automatiquement du XML, et donc par conséquent du SVG. On peut ainsi utiliser le XSL pour indiquer d'ajouter systématiquement les attributs fill="red" stroke="blue" stroke-width="3" aux éléments SVG rect.

On crée pour cela un fichier monstyle.xsl contenant

  <xsl:template match="svg:rect">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:attribute name="fill">red</xsl:attribute>
      <xsl:attribute name="stroke">blue</xsl:attribute>
      <xsl:attribute name="stroke-width">3</xsl:attribute>
    </xsl:copy>
  </xsl:template>

puis on ajoute dans l'en-tête du fichier SVG :

<?xml-stylesheet href="monstyle.xsl" type="application/xml"?>


Pour plus de détails voir : Programmation XML/XSLT et Programmation XML/XSL-FO.

Les métadonnées (metadata) sont des informations sur le fichier lui-même. La présence de métadonnées facilite le traitement automatique des données, par exemple leur recensement, leur catégorisation. Le W3C a développé une norme appelée RDF (resource description framework) et sa mise en œuvre dans le XML.

L'intégration de métadonnées nécessite de déclarer les espaces de nom rdf auquel nous ajoutons rdfs (RDF schema) et dc (Dublin core) qui fournissent une syntaxe.

<?xml version="1.0" standalone="yes"?>
<svg width="4cm" height="3cm" version="1.1"
    xmlns = "http://www.w3.org/2000/svg">
  <desc>
    <title> Le titre </title>
    <descr> La description.</descr>
 </desc>
  <metadata>
    <rdf:RDF
         xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:rdfs = "http://www.w3.org/2000/01/rdf-schema#"
         xmlns:dc = "http://purl.org/dc/elements/1.1/" >
      <rdf:Description about="http://example.org/myfoo"
           dc:title="Le titre"
           dc:description="La description"
           dc:publisher="Organisation publiant les données"
           dc:date="2017-04-11"
           dc:format="image/svg+xml"
           dc:language="fr" >
        <dc:creator>
          <rdf:Bag>
            <rdf:li>Albane Aaron</rdf:li>
            <rdf:li>Bernard Barnier</rdf:li>
          </rdf:Bag>
        </dc:creator>
      </rdf:Description>
    </rdf:RDF>
  </metadata>
  </svg>

Si l'on veut ajouter des informations sur la licence, on peut déclarer l'espace de nom c (Creative Commons) :

<?xml version="1.0" standalone="yes"?>
<svg width="4cm" height="3cm" version="1.1"
    xmlns = "http://www.w3.org/2000/svg"
    xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:cc="http://creativecommons.org/ns#">
  <desc>
    <title> Le titre </title>
    <descr> La description.</descr>
 </desc>
  <metadata>
    <rdf:RDF>
      <cc:Work
         rdf:about="http://example.org/myfoo">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title> Le titre </dc:title>
        <cc:license
           rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
      </cc:Work>
      <cc:License
         rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
        <cc:permits
           rdf:resource="http://creativecommons.org/ns#Reproduction" />
        <cc:permits
           rdf:resource="http://creativecommons.org/ns#Distribution" />
        <cc:requires
           rdf:resource="http://creativecommons.org/ns#Notice" />
        <cc:requires
           rdf:resource="http://creativecommons.org/ns#Attribution" />
        <cc:permits
           rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
        <cc:requires
           rdf:resource="http://creativecommons.org/ns#ShareAlike" />
      </cc:License>
    </rdf:RDF>
  </metadata>
  </svg>

L'élément a permet de rendre un objet cliquable, le clic menant vers une adresse donnée. L'objet est encapsulé entre des balises <a xlink:href="…"> … </a…>. Par exemple :

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="5cm" height="3cm" viewBox="0 0 5 3" version="1.1"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

  <desc>Example - un lien sur une ellipse ellipse
  </desc>

  <rect x=".01" y=".01" width="4.98" height="2.98" 
        fill="none" stroke="blue"  stroke-width=".03"/>

  <a xlink:href="http://www.w3.org">
    <ellipse cx="2.5" cy="1.5" rx="2" ry="1"
             fill="red" />
  </a>

</svg>
  1. « Animation (SVG 1.1) », sur W3C (consulté le 1er décembre 2018)
  2. « SVG animations », sur SVG WG (consulté le 1er décembre 2018)
  3. (en) Jeremie Patonnier, « Re: Good place to be asking non FF SVG questions? », sur Mozilla FireFox dev-tech-svg mailing list sur Google Groupes, (consulté le 1er septembre 2017)

Chemins < > Le SVG pour l'enseignement