Les dégradés et motifs SVG
Pour donner une couleur unie à une forme SVG, nous utilisons la propriété CSS fill
. Avec les dégradés et les motifs, vous allez pouvoir remplir vos formes ou les contours des formes.
Pour donner une couleur unie à une forme SVG, nous utilisons la propriété CSS fill
. Avec les dégradés et les motifs, vous allez pouvoir remplir vos formes ou les contours des formes.
Pour créer un dégradé linéaire, nous allons utiliser plusieurs éléments SVG, à savoir :
<linearGradient>
: fonction qui concerne un dégradé de couleur linéaire.<radialGradient>
: fonction qui concerne un dégradé de couleur radiale.<stop/>
au minimum deux fois (puisqu'il faut au moins deux couleurs pour réaliser un dégradé), ainsi que l'attribut offset
auquel on indique des valeurs en pourcentage.Un exemple de dégradé linéaire ci-dessous :
<svg width="100" height="100" viewBox="0 0 100 100">
<style>
<![CDATA[
#ex_degrade stop:first-child{stop-opacity:.4;stop-color:--#7d68e8}
]]>
</style>
<defs>
<linearGradient id="ex_degrade" x1="0" y1="0" x2="100%" y2="100%">
<stop offset="20%" />
<stop offset="90%" stop-color="#01FF89" />
</linearGradient>
</defs>
<rect x="0" y="0" width="100" height="100" fill="url(#ex_degrade)" />
</svg>
Détaillons le code. Nous avons donc défini le type de dégradé à l'intérieur de l'élément defs
. Puis, nous avons utilisé deux points pour définir ce dégradé. Vous pouvez remarquer dans le premier élément stop
qu'il n'y a pas de couleur. En fait, celle-ci se trouve dans le CSS :
stop:first-child{
stop-opacity: .4;
stop-color: #7A5FFF
}
En effet, dans le CSS, nous avons indiqué une couleur et une opacité pour le premier (avec la propriété first-child
) élément stop
. Pourquoi avoir mis ces valeurs dans le CSS ? Tout simplement pour vous faire découvrir deux propriétés CSS : stop-opacity
et stop-color
.
💡 NB : il aurait également été possible d'utiliser uniquement la propriété stop-color
au format RGB ou HSL pour la transparence (ex: hsla(250, 100%, 69%, 0.4)
).
Par défaut, la direction du dégradé est de gauche à droite horizontalement (x2
est égal à 100%). Si vous souhaitez changer la direction, il existe quatre attributs :
x1
y1
x2
y2
Il y a deux façons d'utiliser ces attributs.
1-Soit en utilisant le système de coordonnées gradientUnits
avec la valeur objectBoundingBox
. Il s'agit de la valeur par défaut. Inutile donc de la renseigner. Dans ce cas, on indique les attributs en pourcentage.
2-Soit en utilisant le même système de coordonnées mais avec la valeur userSpaceOnUse
. Dans ce cas-ci, on renseigne les coordonnées avec l'unité de mesure que l'on a indiquée au document SVG comme ci-dessous :
<svg width="100" height="100" viewBox="0 0 100 100">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" id="ex_degrade1" x1="0" y1="0" x2="100" y2="100">
<stop offset="20%" stop-color="#7A5FFF"/>
<stop offset="90%" stop-color="#01FF89" />
</linearGradient>
</defs>
<rect x="0" y="0" width="100" height="100" fill="url(#ex_degrade1)" />
</svg>
En effet, en utilisant cette valeur, on dessine un dégradé non pas sur la forme elle-même mais sur le document SVG entier.
Mais il y a un autre attribut pour gérer la direction d'un dégradé : gradientTransform
. Cela fonctionne comme pour les transformations CSS :
<svg width="100" height="100" viewBox="0 0 100 100">
<defs>
<linearGradient id="ex_degrade2" gradientTransform="rotate(45)">
<stop offset="0%" stop-color="#7d68e8"/>
<stop offset="100%" stop-color="#7d68e8" />
</linearGradient>
</defs>
<rect x="0" y="0" width="100" height="100" fill="url(#ex_degrade2)" />
</svg>
Un autre attribut, moins connu, permet de personnaliser un dégradé linéaire ou radial. Il s'agit de spreadMethod
. Il regroupe trois valeurs :
pad
: valeur par défaut.repeat
: répétition du dégradé.reflect
: le dégradé est réfléchi.Ci-dessous un exemple avec ces valeurs :
<svg width="400" height="120" viewBox="0 0 400 120">
<defs>
<linearGradient id="ex_spreadMethod" x1="20%" y1="30%" x2="40%" y2="80%">
<stop offset="0%" stop-color="#7A5FFF"/>
<stop offset="100%" stop-color="#01FF89"/>
</linearGradient>
<linearGradient id="pad" href="#ex_spreadMethod"/>
<linearGradient id="repeat" href="#ex_spreadMethod" spreadMethod="repeat"/>
<linearGradient id="reflect" href="#ex_spreadMethod" spreadMethod="reflect"/>
</defs>
<rect x="0" y="10" width="100" height="100" fill="url(#pad)"/>
<rect x="150" y="10" width="100" height="100" fill="url(#repeat)"/>
<rect x="300" y="10" width="100" height="100" fill="url(#reflect)"/>
</svg>
Voici maintenant un exemple de dégradé radial :
<svg width="200" height="200" viewBox="0 0 200 200">
<defs>
<radialGradient id="ex_degrade_radial" cx="45%" cy="45%" fx="30%" fy="30%">
<stop offset="0%" stop-color="#ffffff" />
<stop offset="100%" stop-color="#7A5FFF" />
</radialGradient>
</defs>
<circle fill="url(#ex_degrade_radial)" cx="100" cy="100" r="100"/>
</svg>
Nous retrouvons les mêmes attributs que l'on a évoqués plus haut concernant les dégradés linéaires. Intéressons-nous plutôt au système de coordonnées, légèrement différent.
Nous allons utiliser les attributs suivants cx
, cy
et r
(les même que les cercles et les ellipses mais pour un usage différent) ainsi que les attributs fx
et fy
.
cx
: définit la coordonnée suivant l'axe x du plus grand cercle.cy
: définit la coordonnée suivant l'axe y du plus grand cercle.r
: définit le rayon du cercle de fin pour le dégradé radial.fx
: définit la coordonnée de l'axe des abscisses du point focal.fy
: définit la coordonnée de l'axe des abscisses du point focal.linearGradient
et radialGradient
.defs
(mais ce n'est pas une obligation).stop
.fill
ou stroke
.x1
,y1
,x2
,y2
). Concernant le dégradé radial, il existe On peut également utiliser l'attribut gradientTransform
pour les deux types de dégradés.Pour réaliser un motif en SVG, nous allons avoir besoin de l'élément pattern
(un seul suffit pour créer un motif) que l'on place à l'intérieur de l'élément defs
(comme pour les dégradés), auquel on donne un identifiant que l'on reportera via l'attribut fill
dans la forme que l'on souhaite dessiner.
Ci-dessous, un exemple de motif SVG :
<svg>
<defs>
<pattern id="ex_pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<rect x="0" y="0" height="10" width="10" style="fill: #7A5FFF"/>
</pattern>
</defs>
<rect x="0" y="0" height="100%" width="100%" style="fill:url(#ex_pattern)"/>
</svg>
Ci-dessous, la même chose sur du texte (avec l'élément text
) :
<svg width="100%" height="200">
<defs>
<pattern id="textPattern" x="7" y="7" width="10" height="10" patternUnits="userSpaceOnUse">
<rect x="5" y="5" width="5" height="5" fill="#7A5FFF"/>
</pattern>
</defs>
<text x="50%" y="120" dominant-baseline="middle" style="text-anchor:middle;stroke:#7A5FFF;stroke-width:2px;font-size:180px" fill="url(#textPattern)">Motif SVG</text>
</svg>
Comme pour les dégradés, il est possible de créer un motif en utilisant du pur SVG, en mélangeant SVG et CSS ou en passant par JavaScript avec SVG.JS ou Textures.js.
Dans l'exemple ci-dessous, nous utilisons du CSS, via la propriété background-image
dans laquelle on renseigne le motif au format SVG :
.motif {
height: 200px;
background-color: #f33;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" Transform="rotate(45)" viewBox="0 0 100 100">\a <g fill="rgba(0,0,0,0.3)" stroke-dasharray="3" stroke="rgba(0,0,0,0.2)">\a <rect width="100" height="33" />\a <line x1="33" y1="0" x2="33" y2="100" />\a <line x1="0" y1="66.66" x2="100" y2="66.66" />\a <rect width="33" height="100" x="66" />\a </g>\a</svg>');
background-size: 10%;
background-position: 30%;
}
Même principe ci-dessous, mais en utilisant le pseudo-élément ::after
qui va nous permettre de superposer un motif SVG sur une image :
.motif-svg {
position: relative;
height: 420px;
background: url("image.jpg") center / cover no-repeat;
}
.motif-svg::after{
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cdefs%3E%3Cpattern%20id%3D%22a%22%20patternUnits%3D%22userSpaceOnUse%22%20width%3D%225%22%20height%3D%225%22%20patternTransform%3D%22rotate(45)%22%3E%3Cpath%20stroke%3D%22%23000%22%20d%3D%22M1%200v5%22%2F%3E%3C%2Fpattern%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%23a)%22%2F%3E%3C%2Fsvg%3E");
opacity: .5
}
Autre exemple, avec, cette fois-ci, l'élément mask
que l'on utilise conjointement avec un pattern SVG :
<svg>
<defs>
<pattern id="votreid" width="4" height="4" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
<rect width="2" height="4" transform="translate(0,0)" fill="white"></rect>
</pattern>
<mask id="votreid1">
<rect x="0" y="0" width="100%" height="100%" fill="url(#votreid)" />
</mask>
</defs>
<rect class="motif-svg" x="0" y="0" width="100%" height="100"></rect>
</svg>
.motif-svg{
mask: url(#votreid1);
fill: #7A5FFF;
}
Ci-dessous, un exemple sans CSS, en pur SVG :
<svg width="600" height="120" viewBox="0 0 600 120">
<defs>
<pattern id="votreid" width="10" height="10" patternUnits="userSpaceOnUse">
<path fill="#7A5FFF" d="M5,0 10,10 0,10 Z" />
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#votreid)" />
</svg>
Exemple avec JavaScript (bibliothèque d3.js):
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<svg id=ex-patt width="200" height="200" viewBox="0 0 200 200">
<defs>
<pattern id="patt-ex" width="8" height="8" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
<rect width="4" height="8" fill="#7A5FFF"/>
</pattern>
</defs>
<circle cx="100" cy="100" r="100" fill="url(#patt-ex)"/>
</svg>
let svg = d3.select("#ex-patt").append("svg").attr("id", "d3svg")
.attr("width", 200)
.attr("height", 200);
let pattern = svg.append("defs")
.append("pattern")
.attr(
{
id:"patt-ex",
width:"8",
height:"8",
patternUnits:"userSpaceOnUse",
patternTransform:"rotate(45)"
}
);
Source origine exemple