Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Graphisme > Divers > Le SVG > Les graphiques vectoriels > Styliser vos formes > Lecture du tutoriel

Styliser vos formes

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : dark_popol
Visualisations : 2 137

Plus d'informations Plus d'informations
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.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

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 :
Code : XML
1
2
...
<circle r="20" cx="340" cy="230" style="fill:red;stroke:#3BD200;" />...


stroke-opacity


Indique l'opacité du trait :
Code : XML
1
2
3
...
<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 :
Code : XML
1
2
3
...
<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 :
Mais... o_O Un seul des angles est pointu ! Les deux premiers sont tronqués ! :( Pourquoi donc ? :o Moi, je m'attendais à ça : Image utilisateur...

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) :
Code : XML
1
2
3
...
<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é :Code : XML
1
2
3
...
<line x1="20" y1="200" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;stroke-dasharray:10,20;" />
...
Remarquez que je n'utilise pas stroke-linejoin, car c'est une simple ligne et elle n'a donc pas d'angle, et je n'utilise pas stroke-linecap non plus, car je désire laisser la valeur butt, par défaut.

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 :Code : XML
1
2
3
...
<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

Vous devez porter une attention plus particulière aux valeurs de stroke-dasharray lorsque vous utilisez cette propriété ainsi que stroke-linecap avec une valeur autre que butt (square ou round). En effet, rappelez-vous que ces deux valeurs tracent respectivement un carré et un cercle dont la moitié dépasse de la ligne.

Reprenons notre premier code, et rajoutons-lui la propriété stroke-linecap, avec une valeur de round :
Code : XML
1
2
3
...
<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 :Code : XML
1
2
3
...
<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.
Seulement, on a un petit problème.
Ce code (à titre d'exemple, à ne pas essayer) :Code : XML
1
2
3
...
<line x1="20" y1="200" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;stroke-linecap:round;stroke-dasharray:0,17;" />
...

qui fonctionne parfaitement sur IE :

Image utilisateur


bug complètement sur FF, à cause justement du 0 de stroke-dasharray :

Image utilisateur

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 !
Code : XML
1
2
3
...
<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;" />
...

Encore une fois, vous devez écrire votre nombre décimal avec un point et non une virgule.


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 :
Code : XML
1
2
3
...
<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) :
Code : XML
1
2
3
...
<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 :Code : XML
1
2
3
...
<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 :Code : XML
1
2
3
...
<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 :Code : XML
1
2
3
...
<line x1="20" y1="100" x2="640" y2="200" style="fill:none;stroke:black;stroke-width:7;" />
...
deviendrait comme ça :Code : XML
1
2
3
...
<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. ;)

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 :Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
...
<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.
Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
...
<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 :Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
...
<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.
Pour savoir quoi mettre dans ces attributs, vous devez trouver les dimensions du plus petit rectangle pouvant englober votre marqueur. C'est ce que j'appelle la boîte du marqueur.

Dans notre cas, le marqueur mesure 10*10 pixels, on écrira donc :Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
...
<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);" />
...
Si vous indiquez une boîte du marqueur plus petite que l'espace que prend véritablement votre marqueur, votre marqueur ne sera pas redimensionné ; il sera tronqué. Vous pouvez l'essayer pour voir le résultat.

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.
Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
...
<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 :Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
...
<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

Remarquez qu'on aurait aussi pu écrire un angle de rotation pour le marqueur à la place de auto. (Ex. : orient="45" aurait fait pivoter le marqueur de 45°.)


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 :Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
...
<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 :Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
...
<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 :Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
...
<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,Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
...
<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é.
Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
...
<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 : Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
...
<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 !

Q.C.M.

Lorsque nous utilisons la propriété stroke-linejoin avec une valeur de miter, que faut-il faire pour que tous les angles de la forme soient pointus ?
À quoi sert la propriété stroke-linecap ?
Quelle est l'astuce permettant de faire des pointillés sur une ligne sans faire boguer Firefox ?
Comment faire pour définir un point dans la boîte du marqueur qui doit s'aligner exactement avec le point de début ou de fin d'une ligne ?

Statistiques de réponses au QCM


Et voilà ! Vous avez maintenant de belles formes colorées et stylisées ! :D
Chapitre précédent Sommaire Chapitre suivant
Retour en haut Retour en haut


Créé : le 06/12/2005 à 22:39:11
Modifié : le 22/08/2008 à 15:56:33
Avancement : 0%
Licence : Copie non autorisée

0 commentaire

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 169 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.075s (0.0638s)