Blog
Aller au contenu

Guillaume Duverger

Développement & graphisme


Accueil » Développement » Apprendre SVG » Dégradés et motifs SVG

Sommaire
  1. Les dégradés SVG
    1. dégradé linéaire
    2. dégradé radial
  2. Les motifs SVG
    1. méthodes avec CSS
    2. méthode en pur SVG
    3. méthode avec JavaScript
Télécharger ce cours en pdf

👉 Les dégradés 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.

Dégradé linéaire :

Pour créer un dégradé linéaire, nous allons utiliser plusieurs éléments SVG, à savoir :

  • un identifiant (id) unique.
  • <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 :

Exemple dégradé svg


<svg width="100" height="100" viewBox="0 0 100 100">
<style>
<![CDATA[ 
#ex_degrade stop:first-child{stop-opacity:.4;stop-color:var(--theme-couleur)} 
]]> 
</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.

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.

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="var(--theme-couleur)"/>
<stop offset="100%" stop-color="var(--theme-couleur1)" />
</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 :

Exemple dégradé linéaire svg


<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>



Dégradé radial :

Voici maintenant un exemple de dégradé radial :

Exemple dégradé radial svg


<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.

💡 A retenir à propos des dégradés en SVG :

  1. Il existe deux types de dégradés : linéaire et radial représentés respectivement par les éléments linearGradient et radialGradient.
  2. On définit un dégradé à l'intérieur de l'élément defs (mais ce n'est pas une obligation).
  3. On construit un dégradé avec au minimum deux points via l'élément stop.
  4. Il faut impérativement attribuer un identifiant que l'on reporte à notre forme/image/texte via l'attribut fill ou stroke.
  5. Il existe quatre attributs pour la direction du dégradé linéaire (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.

👉 Les motifs SVG :

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 :

Exemple 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) :

Exemple motif texte svg


<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.

Méthodes avec CSS :

Dans l'exemple ci-dessous, nous utilisons du CSS, via la propriété background-image dans laquelle on renseigne le motif au format SVG :

Exemple motif 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 :

Exemple motif svg


.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 :

Exemple motif 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;

} 



Méthode en pur SVG :

Ci-dessous, un exemple sans CSS, en pur SVG :

Exemple motif 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>



Méthode avec JavaScript :

Exemple avec JavaScript (bibliothèque d3.js):

Exemple motif svg


<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