Documentation

Everything it does, on one page.

GradFlow is one React component. It renders a canvas, fills its parent, and animates a gradient on the GPU.

Installation

The package has no dependencies of its own. It needs React 18 or newer.

Source codebash
npm install gradflow

Usage

The canvas takes the size of its parent, so give the parent a size and a position. Placing the gradient in an absolutely positioned layer with a negative z-index keeps it behind your content; isolate on the section stops that layer from slipping behind the page background.

hero.tsxtsx
import { GradFlow } from 'gradflow'

export default function Hero() {
  return (
    <section className="relative isolate h-screen">
      <div className="absolute inset-0 -z-10">
        <GradFlow preset="borealis" />
      </div>

      <h1>Your content, on top.</h1>
    </section>
  )
}

GradFlow is a client component. You can import it from a server component without adding 'use client' yourself.

Props

NameTypeDefaultDescription
presetPresetNamenoneStart from one of the built-in looks.
configGradientConfigInputaurora defaultsType, colors, speed, scale and noise. Overrides the preset field by field.
transitionnumber700Milliseconds a config or preset change takes to blend in. 0 switches instantly.
interactivebooleanfalseLet the pattern swell under the pointer.
pausedbooleanfalseFreeze the animation on a single frame.
preserveDrawingBufferbooleanfalseKeep the canvas readable for toBlob and toDataURL.
classNamestringnoneClasses for the canvas element.
refRef<HTMLCanvasElement>noneForwarded to the canvas.

Config

Every field is optional. Anything you leave out comes from the preset if you passed one, and from the defaults otherwise.

NameTypeDefaultDescription
typeGradientType'aurora'One of the 20 shaders below.
color1string | RGB#d21570Hex string or { r, g, b } with 0 to 255 channels.
color2string | RGB#8c3ff8Same formats as color1.
color3string | RGB#56ffc3Same formats as color1.
speednumber0.5Animation rate. 0 stops time; around 0.3 to 1 reads as ambient.
scalenumber1.2Zoom of the pattern. Higher values show more, finer detail.
noisenumber0.32Film grain from 0 to 0.5. Hides banding on wide, soft ramps.
Source codetsx
<GradFlow
  config={{
    type: 'prism',
    color1: '#ff5a1e',
    color2: { r: 60, g: 110, b: 255 },
    color3: '#78d2ff',
    speed: 0.5,
    scale: 1,
    noise: 0.1,
  }}
/>

Gradient types

20 shaders. Click one to open it in the playground.

Presets

22 ready-made looks. A preset sets every config field; pass config alongside it to change some of them.

Source codetsx
// a preset on its own
<GradFlow preset="magma" />

// a preset with one thing changed
<GradFlow preset="magma" config={{ speed: 0.2 }} />

Transitions

When preset or config changes, the canvas blends to the new look instead of jumping. Colors, speed, scale and noise interpolate; a change of type dissolves the old pattern into the new one along a noise front. transition sets the duration in milliseconds, and 0 turns blending off.

Source codetsx
const [preset, setPreset] = useState<PresetName>('lagoon')

// the canvas blends from one look to the next over 1.2 seconds
<GradFlow preset={preset} transition={1200} />

<button onClick={() => setPreset('sahara')}>Evening</button>

Changing speed never makes the pattern skip. Time is accumulated frame by frame, so a faster speed only means the pattern moves faster from where it already is.

Pointer interaction

With interactive set, the pattern is magnified under the pointer and the effect trails behind fast movement. The pointer is tracked on the window, so it keeps working when the canvas sits behind other content.

Source codetsx
<GradFlow preset="atlas" interactive />

Exporting a still

The ref points at the canvas element. Browsers clear a WebGL canvas after each frame is shown, so set preserveDrawingBuffer on any gradient you intend to read back.

Source codetsx
const canvas = useRef<HTMLCanvasElement>(null)

const save = () =>
  canvas.current?.toBlob((blob) => {
    if (blob) window.open(URL.createObjectURL(blob))
  })

<GradFlow ref={canvas} preset="spectrum" preserveDrawingBuffer />

Performance

A gradient is one triangle and one fragment shader, rendered at up to twice the device pixel ratio. The render loop stops while the canvas is off screen and while the tab is hidden, and starts again on its own.

Each GradFlow owns a WebGL context. Browsers allow roughly sixteen per page and drop the oldest past that, so keep the number of gradients mounted at once in single digits. If a context is lost, GradFlow rebuilds its program when the browser restores it.

Accessibility

Visitors who ask their system for reduced motion get one still frame of the gradient, with the pointer effect off. Use paused to give everyone a control over it, and keep enough contrast between your text and the brightest part of the pattern; a scrim over the edge your text sits on is usually enough.