L’essentiel en bref
- Un dégradé canvas HTML est un objet CanvasGradient créé avec createLinearGradient, createRadialGradient ou createConicGradient, doté d’arrêts de couleur via addColorStop, puis affecté à fillStyle ou strokeStyle.
- Les dégradés canvas utilisent des coordonnées dans l’espace du canvas, pas des angles ni des pourcentages, donc un dégradé linéaire a besoin d’un point de départ et d’un point d’arrivée.
- Les positions des arrêts vont de 0 à 1, et toute chaîne de couleur CSS est acceptée, y compris hex, rgb(), hsl() et oklch() dans les navigateurs actuels.
- createConicGradient commence son balayage depuis une ligne orientée vers la droite et mesure l’angle en radians, contrairement à conic-gradient en CSS, qui part du haut en degrés.
- Sur les écrans haute densité, dimensionnez le tampon du canvas selon devicePixelRatio, sinon dégradés et texte paraissent flous.
Sur cette page
Un dégradé canvas HTML se fait en trois étapes : créer un objet dégradé avec ctx.createLinearGradient(), createRadialGradient() ou createConicGradient(), ajouter des couleurs avec addColorStop(offset, colour), puis l’affecter à ctx.fillStyle et dessiner. Contrairement au CSS, un dégradé canvas est défini par des points en pixels, vous lui indiquez donc exactement où la couleur commence et finit. Tout ce que vous peignez avec ce remplissage reprend la partie du dégradé située en dessous.
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
const g = ctx.createLinearGradient(0, 0, canvas.width, canvas.height)
g.addColorStop(0, '#1e1b4b')
g.addColorStop(0.55, '#7c3aed')
g.addColorStop(1, '#f472b6')
ctx.fillStyle = g
ctx.fillRect(0, 0, canvas.width, canvas.height)Les trois méthodes de dégradé
createLinearGradientArguments
x0, y0, x1, y1Équivalent CSS
linear-gradient()createRadialGradientArguments
x0, y0, r0, x1, y1, r1Équivalent CSS
radial-gradient()createConicGradientArguments
startAngle, x, yÉquivalent CSS
conic-gradient()addColorStopArguments
offset de 0 à 1, colourÉquivalent CSS
Le dégradé est fixé au canvas, pas à la forme. Si vous créez un dégradé de 0 à 400 puis remplissez un petit carré à x 300, le carré ne montre que l’extrémité rose. Cela surprend quand on vient du CSS, où un dégradé s’étire toujours sur l’élément. Créez le dégradé avec les coordonnées de la forme elle-même quand vous voulez qu’il s’y ajuste.
createLinearGradient et les angles CSS
Le CSS vous laisse écrire 135deg. Le canvas veut deux points. Cette fonction convertit un angle CSS en points de départ et d’arrivée identiques à ceux qu’utilise le CSS, pour qu’une création écrite en dégradé linéaire CSS s’affiche à l’identique sur canvas.
// Match CSS linear-gradient(angle) on a w by h rectangle
function cssAngleGradient(ctx, angleDeg, x, y, w, h) {
const a = (angleDeg * Math.PI) / 180
const len = Math.abs(w * Math.sin(a)) + Math.abs(h * Math.cos(a))
const cx = x + w / 2
const cy = y + h / 2
const dx = (Math.sin(a) * len) / 2
const dy = (-Math.cos(a) * len) / 2
return ctx.createLinearGradient(cx - dx, cy - dy, cx + dx, cy + dy)
}
const g = cssAngleGradient(ctx, 135, 0, 0, 1200, 630)
g.addColorStop(0, '#0f172a')
g.addColorStop(1, '#0d9488')
ctx.fillStyle = g
ctx.fillRect(0, 0, 1200, 630)linear-gradient(135deg, #0f172a 0%, #0d9488 100%)createRadialGradient
Sur canvas, un dégradé radial est défini par deux cercles : un cercle de départ et un cercle d’arrivée. L’arrêt 0 se trouve sur le premier cercle et l’arrêt 1 sur le second. La plupart du temps, vous voulez que le premier cercle soit un point, donc son rayon vaut 0.
const w = canvas.width
const h = canvas.height
// A soft light in the top right corner of a dark ground
ctx.fillStyle = '#0c0a1d'
ctx.fillRect(0, 0, w, h)
const glow = ctx.createRadialGradient(w * 0.75, h * 0.2, 0, w * 0.75, h * 0.2, w * 0.6)
glow.addColorStop(0, 'rgb(124 58 237 / 0.9)')
glow.addColorStop(0.5, 'rgb(46 16 101 / 0.5)')
glow.addColorStop(1, 'rgb(12 10 29 / 0)')
ctx.fillStyle = glow
ctx.fillRect(0, 0, w, h)Éloignez le centre du premier cercle de celui du second et la lumière s’incline, comme un projecteur qui frappe un mur en biais. Le CSS n’a pas d’équivalent direct de ce décalage. Côté CSS, voir les dégradés radiaux CSS.
createConicGradient
createConicGradient(startAngle, x, y) fait tourner la couleur autour d’un point central. Deux détails diffèrent du CSS : l’angle est en radians, et 0 pointe vers la droite (trois heures), pas vers le haut. Pour reproduire un conic-gradient(from 0deg, ...) CSS, commencez à -Math.PI / 2.
const cx = canvas.width / 2
const cy = canvas.height / 2
const ring = ctx.createConicGradient(-Math.PI / 2, cx, cy)
ring.addColorStop(0, '#22d3ee')
ring.addColorStop(0.33, '#7c3aed')
ring.addColorStop(0.66, '#f472b6')
ring.addColorStop(1, '#22d3ee')
ctx.fillStyle = ring
ctx.beginPath()
ctx.arc(cx, cy, 160, 0, Math.PI * 2)
ctx.fill()Texte en dégradé, contours et animation
fillStyle et strokeStyle acceptent tous deux un dégradé, donc le texte et les contours fonctionnent de la même façon. Placez le dégradé sur la boîte du texte lui-même, mesurée avec measureText(), pour que toute la gamme de couleurs apparaisse dans les lettres.
ctx.font = '700 96px Inter, system-ui, sans-serif'
const text = 'Open late'
const width = ctx.measureText(text).width
const tg = ctx.createLinearGradient(80, 0, 80 + width, 0)
tg.addColorStop(0, '#fde68a')
tg.addColorStop(1, '#fb7185')
ctx.fillStyle = tg
ctx.fillText(text, 80, 200)
// Animation: rebuild the gradient each frame, it is cheap
function frame(t) {
const shift = (Math.sin(t / 2000) + 1) / 2
const g = ctx.createLinearGradient(0, 0, canvas.width, 0)
g.addColorStop(0, '#1e1b4b')
g.addColorStop(0.2 + shift * 0.6, '#7c3aed')
g.addColorStop(1, '#0f172a')
ctx.fillStyle = g
ctx.fillRect(0, 0, canvas.width, canvas.height)
requestAnimationFrame(frame)
}
requestAnimationFrame(frame)Enregistrer le canvas en image
Une raison courante de dessiner des dégradés sur canvas est de générer une image : une carte de partage, un certificat, une couverture. Appelez canvas.toBlob() avec image/png pour les dégradés et le texte, car le PNG garde les fondus lisses intacts, et réservez le JPEG aux images surtout photographiques. PNG ou JPG explique le compromis. Dessinez à la taille de sortie réelle, comme 1200×630 pour un aperçu de lien, plutôt que d’agrandir un petit canvas.
canvas.toBlob((blob) => {
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = 'card.png'
a.click()
setTimeout(() => URL.revokeObjectURL(a.href), 1000)
}, 'image/png')Problèmes courants des dégradés canvas
Symptôme
- Le dégradé paraît flou sur un téléphone
- Une seule couleur apparaît dans une forme
- Des bandes visibles dans un dégradé sombre
IndexSizeErrorvenant d’addColorStop- Le dégradé conique commence au mauvais endroit
Correctif
- Multipliez largeur et hauteur du canvas par
devicePixelRatio, puis revenez avecctx.scale() - Créez le dégradé avec les coordonnées de la forme, pas celles du canvas
- Ajoutez un léger bruit par-dessus, voir l’effet de bandes des dégradés
- Gardez les positions entre 0 et 1
- Commencez à
-Math.PI / 2pour coller au CSS
Quand il vous faut des dégradés qui bougent avec un vrai éclairage plutôt que des fondus plats, le canvas atteint ses limites et WebGL prend le relais, comme l’expliquent les dégradés shader. Et quand le canvas n’est qu’un moyen d’obtenir une image, comme une carte sociale ou une affiche, Gradiently rend un Mark à n’importe quelle taille de 200 à 8 000 px avec les mots mis en page pour vous, sans code de dessin à maintenir.
Les questions qu’on nous pose
Comment créer un dégradé sur un canvas HTML ?
Appelez ctx.createLinearGradient(x0, y0, x1, y1), ajoutez des couleurs avec addColorStop(offset, colour), affectez le dégradé à ctx.fillStyle et dessinez une forme, par exemple avec fillRect.
Quelle différence entre createLinearGradient et linear-gradient en CSS ?
Le canvas utilise un point de départ et un point d’arrivée en pixels, alors que le CSS utilise un angle et étire le dégradé sur l’élément. Une petite fonction peut convertir un angle CSS en points canvas.
Puis-je utiliser des couleurs oklch ou hsl dans addColorStop ?
Oui. addColorStop accepte toute chaîne de couleur CSS que le navigateur comprend, y compris hex, rgb(), hsl() et, dans les navigateurs actuels, oklch().
Pourquoi mon dégradé canvas n’affiche-t-il qu’une couleur ?
Le dégradé est positionné en coordonnées du canvas, donc une forme dessinée hors de ses points de départ et d’arrivée ne reprend que la couleur d’extrémité la plus proche. Créez le dégradé avec la position et la taille de la forme.
Comment animer un dégradé canvas ?
Créez un nouveau dégradé à chaque image de l’animation avec des arrêts ou des coordonnées mis à jour, puis redessinez. Les arrêts d’un dégradé ne peuvent être ni déplacés ni supprimés une fois ajoutés.
Écrit par Gradiently
L’équipe derrière Gradiently, un outil de création construit autour des Marks : des dégradés vivants qui donnent à tout ce que vous créez votre propre signature.
Voir notre profil