Kortversjonen
- En HTML canvas-gradient er et CanvasGradient-objekt laget med createLinearGradient, createRadialGradient eller createConicGradient, med fargestopp fra addColorStop og tilordnet fillStyle eller strokeStyle.
- Canvas-gradienter bruker koordinater i canvas, ikke vinkler eller prosent, så en lineær gradient trenger et startpunkt og et sluttpunkt.
- Posisjonene til fargestoppene går fra 0 til 1, og alle CSS-fargestrenger godtas, blant annet hex, rgb(), hsl() og oklch() i dagens nettlesere.
- createConicGradient starter fra en linje mot høyre og måler vinkelen i radianer, mens CSS conic-gradient starter øverst og bruker grader.
- På skjermer med høy pikseltetthet må canvas-bufferen dimensjoneres med devicePixelRatio, ellers blir gradienter og tekst uskarpe.
På denne siden
En HTML canvas-gradient lages i tre trinn: lag et gradientobjekt med ctx.createLinearGradient(), createRadialGradient() eller createConicGradient(), legg til farger med addColorStop(offset, colour), tilordne det til ctx.fillStyle og tegn. I motsetning til CSS defineres en canvas-gradient med punkter i piksler, så du angir nøyaktig hvor fargen begynner og slutter. Alt du maler med dette fyllet, får den delen av gradienten som ligger under.
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)De tre gradientmetodene
createLinearGradientArgumenter
x0, y0, x1, y1Tilsvarende CSS
linear-gradient()createRadialGradientArgumenter
x0, y0, r0, x1, y1, r1Tilsvarende CSS
radial-gradient()createConicGradientArgumenter
startAngle, x, yTilsvarende CSS
conic-gradient()addColorStopArgumenter
offset 0 til 1, colourTilsvarende CSS
Gradienten er knyttet til canvas, ikke formen. Lager du en gradient fra 0 til 400 og fyller en liten firkant ved x 300, viser firkanten bare den rosa enden. Det overrasker dem som kommer fra CSS, der gradienten alltid strekkes til elementet. Bruk formens egne koordinater når gradienten skal passe i den.
createLinearGradient og CSS-vinkler
I CSS kan du skrive 135deg. Canvas trenger to punkter. Denne hjelpefunksjonen gjør en CSS-vinkel om til de samme start- og sluttpunktene som CSS bruker, slik at et design skrevet som en lineær CSS-gradient gjengis likt på 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
En radial gradient på canvas defineres av to sirkler: en startsirkel og en sluttsirkel. Fargestopp 0 ligger på den første, og stopp 1 på den andre. Som regel bør den første sirkelen være et punkt, med radius 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)Flytt sentrum av den første sirkelen bort fra den andre, så vinkles lyset som en lyskaster som treffer en vegg på skrå. CSS har ingen direkte motsvarighet til denne forskyvningen. For CSS-versjonen, se radiale CSS-gradienter.
createConicGradient
createConicGradient(startAngle, x, y) fordeler farge rundt et midtpunkt. To detaljer skiller seg fra CSS: vinkelen er i radianer, og 0 peker mot høyre, klokken tre, ikke oppover. For å matche CSS conic-gradient(from 0deg, ...), start ved -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()Gradienttekst, konturer og animasjon
Både fillStyle og strokeStyle godtar en gradient, så tekst og konturer fungerer likt. Legg gradienten over tekstens egen boks, målt med measureText(), slik at hele fargespekteret vises inni bokstavene.
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)Lagre canvas som et bilde
En vanlig grunn til å tegne gradienter på canvas er å lage et bilde: et delingskort, et sertifikat eller et omslag. Bruk canvas.toBlob() med image/png for gradienter og tekst, fordi PNG bevarer myke overganger. Bruk JPEG bare når bildet hovedsakelig er et foto. PNG mot JPG forklarer avveiningen. Tegn i den faktiske størrelsen, for eksempel 1200×630 for en lenkeforhåndsvisning, fremfor å forstørre et lite 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')Vanlige problemer med canvas-gradienter
Symptom
- Gradienten er uskarp på telefonen
- Bare én farge vises i en form
- Synlige striper i en mørk gradient
IndexSizeErrorfra addColorStop- Konisk gradient starter på feil sted
Løsning
- Gang canvas-bredden og høyden med
devicePixelRatio, og skaler tilbake medctx.scale() - Lag gradienten med formens koordinater, ikke canvas sine
- Legg lett støy over, se striper i gradienter
- Hold posisjonene mellom 0 og 1
- Start ved
-Math.PI / 2for å matche CSS
Når du trenger gradienter som beveger seg med ekte lys fremfor flate overganger, når canvas sin grense og WebGL tar over. Det beskrives i shader-gradienter. Når canvas bare brukes for å lage et bilde, for eksempel et innlegg eller en plakat, kan Gradiently gjengi en Mark i alle størrelser fra 200 til 8 000 px og plassere teksten for deg. Da slipper du å vedlikeholde tegnekode.
Spørsmål folk stiller
Hvordan lager jeg en gradient på et HTML canvas?
Kall ctx.createLinearGradient(x0, y0, x1, y1), legg til farger med addColorStop(offset, colour), sett ctx.fillStyle til gradienten og tegn en form, for eksempel med fillRect.
Hva er forskjellen mellom createLinearGradient og CSS linear-gradient?
Canvas bruker et startpunkt og et sluttpunkt i piksler, mens CSS bruker en vinkel og strekker gradienten til elementet. En liten hjelpefunksjon kan gjøre en CSS-vinkel om til canvas-punkter.
Kan jeg bruke oklch- eller hsl-farger i addColorStop?
Ja. addColorStop godtar alle CSS-fargestrenger nettleseren forstår, blant annet hex, rgb(), hsl() og, i dagens nettlesere, oklch().
Hvorfor viser canvas-gradienten min bare én farge?
Gradienten plasseres i canvas-koordinater, så en form utenfor start- og sluttpunktene får bare nærmeste endefarge. Lag gradienten med formens plassering og størrelse.
Hvordan animerer jeg en canvas-gradient?
Lag en ny gradient for hver animasjonsramme med oppdaterte stopp eller koordinater, og tegn på nytt. Fargestopp kan ikke flyttes eller fjernes etter at de er lagt til.
Skrevet av Gradiently
Teamet bak Gradiently, et designverktøy bygget rundt Marks: levende gradienter som gjør at alt du designer ser ut som ditt.
Se profilen vår