Dégradés sur le canvas
Les dégradés HTML5 Canvas remplissent cercles, rectangles, textes et plus. Découvrez les dégradés linéaires, radiaux et coniques avec des exemples.
Un dégradé est, en général, un motif de couleurs qui passe progressivement d'une teinte à une autre. Les dégradés HTML5 Canvas vous permettent de remplir ou de tracer des formes — cercles, rectangles, lignes, texte, tracés quelconques — avec ce type de fondu multicolore plutôt qu'avec une couleur unie.
Ce chapitre couvre les trois types de dégradés que vous pouvez créer dans un contexte 2D, la façon dont leurs paramètres de coordonnées contrôlent la direction et la taille, comment addColorStop() positionne les couleurs le long du dégradé, ainsi que plusieurs exemples exécutables (vertical, diagonal, remplissages de texte et de tracé, et un éclat radial). Si vous débutez avec l'API canvas, commencez par l'introduction au canvas HTML5, puis la page sur le dessin de formes et de tracés, et consultez le fonctionnement du système de coordonnées du canvas.
Fonctionnement des dégradés canvas
Travailler avec un dégradé suit toujours les quatre mêmes étapes :
- Créer un objet dégradé avec l'une des méthodes de fabrique du contexte :
ctx.createLinearGradient(x0, y0, x1, y1)— un dégradé linéaire (directionnel).ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)— un dégradé radial (circulaire).ctx.createConicGradient(startAngle, x, y)— un dégradé conique (balayage angulaire).
- Ajouter deux arrêts de couleur ou plus avec
gradient.addColorStop(offset, color). - Affecter le dégradé à
ctx.fillStyleou àctx.strokeStyle. - Dessiner une forme (
fillRect,fill,stroke,fillText, …). Le dégradé est échantillonné là où vous peignez.
Un point essentiel à comprendre : les coordonnées du dégradé sont dans l'espace du canvas (absolu), pas relatif à la forme que vous remplissez. Un dégradé créé de (0, 0) à (300, 0) couvre toujours cette région du canvas. Si vous dessinez un rectangle en dehors de cette étendue, il prend la première ou la dernière couleur du dégradé (la plus proche), car les couleurs avant l'offset 0 et après l'offset 1 sont écrêtées.
addColorStop() : positionner les couleurs
gradient.addColorStop(offset, color) ajoute un arrêt de couleur au dégradé.
offset— un nombre entre0.0(le début du dégradé) et1.0(la fin). Les valeurs hors de cette plage génèrent une erreur.color— toute chaîne de couleur CSS : un nom ("green"), une valeur hexadécimale ("#14389c"),rgb()/rgba(), ouhsl(). Utilisez le canal alpha (rgba(...)) pour des arrêts transparents.
Il vous faut au moins deux arrêts pour un fondu visible. L'offset de chaque arrêt contrôle l'endroit où la transition se produit — plus l'écart entre deux offsets est faible, plus le changement de couleur est net. Un espacement régulier donne un fondu uniforme ; regrouper les offsets crée des bandes franches.
<!DOCTYPE html>
<html>
<head>
<title>Three color stops</title>
<style>
canvas { border: 1px solid #cccccc; }
</style>
</head>
<body>
<canvas id="stopsCanvas" width="300" height="120"></canvas>
<script>
const ctx = document.getElementById("stopsCanvas").getContext("2d");
const grd = ctx.createLinearGradient(0, 0, 300, 0);
grd.addColorStop(0, "red"); // start
grd.addColorStop(0.5, "yellow"); // exact middle
grd.addColorStop(1, "green"); // end
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 300, 120);
</script>
</body>
</html>Déplacez l'arrêt du milieu de 0.5 à 0.85 et la bande jaune se déplace vers la droite, laissant la majeure partie de la barre en fondu rouge-vers-jaune — c'est l'offset qui contrôle le positionnement.
Dégradé linéaire
ctx.createLinearGradient(x0, y0, x1, y1) retourne un dégradé dont la couleur évolue le long d'une droite — le vecteur de dégradé qui va du point de départ (x0, y0) au point d'arrivée (x1, y1) :
x0, y0— le point de départ du dégradé. L'arrêt de couleur à l'offset0est peint ici.x1, y1— le point d'arrivée du dégradé. L'arrêt de couleur à l'offset1est peint ici.
La direction de la ligne entre ces deux points définit la direction du dégradé, et la distance entre eux détermine jusqu'où le fondu s'étend. Les lignes perpendiculaires au vecteur sont d'une couleur unie.
- Un dégradé horizontal maintient
yconstant :createLinearGradient(0, 0, 300, 0). - Un dégradé vertical maintient
xconstant :createLinearGradient(0, 0, 0, 200). - Un dégradé diagonal modifie les deux :
createLinearGradient(0, 0, 300, 200).
Rappelez-vous le système de coordonnées du canvas : (0, 0) est le coin supérieur gauche, x augmente vers la droite et y augmente vers le bas.
Exemple de dégradé linéaire horizontal avec fillStyle
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
canvas {
border: 1px solid #cccccc;
}
</style>
</head>
<body>
<canvas id="exampleCanvas" width="300" height="150">
Your browser doesn't support the HTML5 canvas tag.
</canvas>
<script>
var c = document.getElementById("exampleCanvas");
var ctx = c.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, 300, 0);
grd.addColorStop(0, "green");
grd.addColorStop(1, "whitesmoke");
ctx.fillStyle = grd;
ctx.fillRect(20, 20, 260, 110);
</script>
</body>
</html>Le vecteur allant de (0, 0) à (300, 0), le fondu est purement horizontal : le bord gauche est vert et le bord droit est whitesmoke.
Exemple de dégradé linéaire vertical
Gardez x identique dans les deux points (ici 0) et modifiez uniquement y pour créer un fondu de haut en bas :
<!DOCTYPE html>
<html>
<head>
<title>Vertical gradient</title>
<style>
canvas { border: 1px solid #cccccc; }
</style>
</head>
<body>
<canvas id="verticalCanvas" width="300" height="200"></canvas>
<script>
const ctx = document.getElementById("verticalCanvas").getContext("2d");
// Same x (0), different y → top-to-bottom blend.
const grd = ctx.createLinearGradient(0, 0, 0, 200);
grd.addColorStop(0, "#1e3c72"); // top
grd.addColorStop(1, "#2a5298"); // bottom
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 300, 200);
</script>
</body>
</html>Exemple de dégradé linéaire diagonal
Modifiez à la fois x et y pour que le vecteur aille d'un coin à l'autre :
<!DOCTYPE html>
<html>
<head>
<title>Diagonal gradient</title>
<style>
canvas { border: 1px solid #cccccc; }
</style>
</head>
<body>
<canvas id="diagonalCanvas" width="300" height="200"></canvas>
<script>
const ctx = document.getElementById("diagonalCanvas").getContext("2d");
// Vector from the top-left corner to the bottom-right corner.
const grd = ctx.createLinearGradient(0, 0, 300, 200);
grd.addColorStop(0, "#ff512f");
grd.addColorStop(0.5, "#f09819");
grd.addColorStop(1, "#ffd452");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 300, 200);
</script>
</body>
</html>Exemple de dégradé linéaire avec fillStyle et différentes couleurs :
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
canvas {
border: 2px solid #202131;
}
</style>
</head>
<body>
<canvas id="exampleCanvas" width="500" height="200"></canvas>
<script>
var canvas = document.getElementById('exampleCanvas');
var context = canvas.getContext('2d');
context.rect(0, 0, 500, 200);
var linear = context.createLinearGradient(0, 0, 500, 200);
linear.addColorStop(0, '#297979');
linear.addColorStop(1, '#2ee035');
context.fillStyle = linear;
context.fill();
</script>
</body>
</html>Exemple de dégradé linéaire avec fillStyle et strokeStyle :
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
canvas {
border: 5px solid #cccccc;
}
</style>
<script>
function drawShape() {
var canvas = document.getElementById('canvasGradient');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var lgrad1 = ctx.createLinearGradient(0, 0, 0, 300);
lgrad1.addColorStop(0, 'blue');
lgrad1.addColorStop(0.4, 'lightpink');
lgrad1.addColorStop(0.5, 'purple');
lgrad1.addColorStop(1, 'lightsalmon');
var lgrad2 = ctx.createLinearGradient(0, 50, 0, 150);
lgrad2.addColorStop(0, '#7afff3');
lgrad2.addColorStop(0.5, '#191918');
lgrad2.addColorStop(1, '#7afff3');
ctx.fillStyle = lgrad1;
ctx.strokeStyle = lgrad2;
ctx.fillRect(15, 15, 120, 120);
ctx.strokeRect(100, 50, 100, 50);
} else {
alert('Your browser does not support');
}
}
</script>
</head>
<body onload="drawShape();">
<canvas id="canvasGradient" width="300" height="300"></canvas>
</body>
</html>Exemple de dégradé sur du texte et un tracé
Un dégradé ne se limite pas aux rectangles — il fonctionne avec n'importe quel remplissage ou tracé, y compris le texte et les tracés personnalisés. Définissez-le comme fillStyle avant fillText() (voir dessiner du texte sur le canvas), ou avant fill()/stroke() sur un tracé que vous avez construit (voir dessin sur le canvas).
<!DOCTYPE html>
<html>
<head>
<title>Gradient text and path</title>
<style>
canvas { border: 1px solid #cccccc; }
</style>
</head>
<body>
<canvas id="textCanvas" width="400" height="160"></canvas>
<script>
const ctx = document.getElementById("textCanvas").getContext("2d");
// A gradient spanning the canvas width.
const grd = ctx.createLinearGradient(0, 0, 400, 0);
grd.addColorStop(0, "#8e2de2");
grd.addColorStop(1, "#4a00e0");
// Fill text with the gradient.
ctx.font = "bold 48px sans-serif";
ctx.fillStyle = grd;
ctx.fillText("Gradient", 30, 70);
// Stroke a triangular path with the same gradient.
ctx.beginPath();
ctx.moveTo(40, 100);
ctx.lineTo(360, 100);
ctx.lineTo(200, 145);
ctx.closePath();
ctx.lineWidth = 6;
ctx.strokeStyle = grd;
ctx.stroke();
</script>
</body>
</html>Dégradé radial
ctx.createRadialGradient(x0, y0, r0, x1, y1, r1) définit un dégradé entre deux cercles. La couleur se fond de l'extérieur du cercle de départ vers le cercle d'arrivée :
x0, y0, r0— le centre(x0, y0)et le rayonr0du cercle de départ (intérieur). L'arrêt de couleur à l'offset0remplit ce cercle.x1, y1, r1— le centre(x1, y1)et le rayonr1du cercle d'arrivée (extérieur). L'arrêt de couleur à l'offset1est atteint au bord de ce cercle.
Lorsque les deux cercles partagent le même centre, vous obtenez un éclat parfaitement concentrique. Lorsque le centre du cercle intérieur est décalé par rapport à l'extérieur, le point lumineux se déplace d'un côté — c'est exactement ainsi que l'on simule une source lumineuse ou un reflet brillant (l'exemple ci-dessous utilise des centres décalés). Donner à r0 une valeur supérieure à 0 produit un noyau solide de la première couleur avant que le fondu ne commence.
Exemple de dégradé radial avec centres décalés
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
canvas {
border: 2px solid #cccccc;
}
</style>
</head>
<body>
<canvas id="exampleCanvas" width="300" height="150">
Your browser doesn't support the HTML5 canvas tag.
</canvas>
<script>
var c = document.getElementById("exampleCanvas");
var ctx = c.getContext("2d");
var grd = ctx.createRadialGradient(155, 80, 20, 130, 40, 190);
grd.addColorStop(0, "#14389c");
grd.addColorStop(1, "white");
ctx.fillStyle = grd;
ctx.fillRect(15, 15, 270, 120);
</script>
</body>
</html>Ici, le cercle intérieur est centré en (155, 80) avec un rayon de 20, tandis que le cercle extérieur est centré en (130, 40) avec un rayon de 190. Comme les centres diffèrent, le noyau bleu foncé se situe vers le bas à droite et s'estompe vers le blanc de façon décentrée, donnant au remplissage un aspect tridimensionnel, éclairé d'un côté.
Exemple d'éclat radial
Un petit arrêt extérieur entièrement transparent au-dessus d'une zone de canvas transparente crée un éclat doux que vous pouvez superposer à d'autres dessins. Notez l'utilisation de rgba() pour que le bord s'estompe jusqu'au transparent plutôt que jusqu'au blanc :
<!DOCTYPE html>
<html>
<head>
<title>Radial glow</title>
<style>
canvas { border: 1px solid #cccccc; background: #11131f; }
</style>
</head>
<body>
<canvas id="glowCanvas" width="300" height="200"></canvas>
<script>
const ctx = document.getElementById("glowCanvas").getContext("2d");
// Concentric circles: solid core at (150,100), fading out to radius 110.
const grd = ctx.createRadialGradient(150, 100, 5, 150, 100, 110);
grd.addColorStop(0, "rgba(255, 214, 102, 1)"); // bright core
grd.addColorStop(0.4, "rgba(255, 154, 0, 0.6)"); // warm mid
grd.addColorStop(1, "rgba(255, 154, 0, 0)"); // transparent edge
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 300, 200);
</script>
</body>
</html>Dégradé conique
ctx.createConicGradient(startAngle, x, y) crée un dégradé qui fait tourner les couleurs autour d'un point central, comme une roue chromatique ou un camembert, plutôt que le long d'une ligne ou entre des cercles :
startAngle— l'angle en radians auquel l'offset0commence, mesuré dans le sens des aiguilles d'une montre depuis l'axe x positif.x, y— le point central de la rotation.
Les arrêts de couleur sont répartis sur le tour complet, de sorte que l'offset 0 et l'offset 1 se rejoignent à startAngle. Pour éviter une couture visible, donnez aux premier et dernier arrêts la même couleur.
<!DOCTYPE html>
<html>
<head>
<title>Conic gradient</title>
<style>
canvas { border: 1px solid #cccccc; }
</style>
</head>
<body>
<canvas id="conicCanvas" width="200" height="200"></canvas>
<script>
const ctx = document.getElementById("conicCanvas").getContext("2d");
// Sweep starting at the top (-90° = -Math.PI/2), centered at (100,100).
const grd = ctx.createConicGradient(-Math.PI / 2, 100, 100);
grd.addColorStop(0, "red");
grd.addColorStop(0.25, "yellow");
grd.addColorStop(0.5, "lime");
grd.addColorStop(0.75, "blue");
grd.addColorStop(1, "red"); // matches stop 0 → seamless wheel
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 200, 200);
</script>
</body>
</html>createConicGradient() est pris en charge dans les versions actuelles de tous les principaux navigateurs (Chrome, Edge, Firefox et Safari). Fournissez une couleur unie de secours pour les navigateurs très anciens si vous devez les prendre en charge.