Getting Started
Scroll Animations
Text Animations
Hover & Cursor
Sliders & Carousels
Galleries & Grids
Menus & Navigation
Preloaders & Intros
Page Transitions
3D & WebGL
import { FluidGradientCanvas } from "@/registry/tween/fluid-gradient-canvas"
export function FluidGradientCanvasDemo() {
return (
<FluidGradientCanvas>
<div className="pointer-events-none absolute inset-0 flex flex-col justify-between p-[clamp(1.25rem,4cqi,2rem)] font-mono text-[clamp(0.6rem,1cqi,0.75rem)] tracking-[0.18em] text-white/90 uppercase">
<div className="flex items-center justify-between">
<span className="flex items-center gap-2 font-sans text-base font-bold tracking-normal">
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
aria-hidden
>
<circle
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="2"
/>
<path d="M2 12a10 10 0 0 0 20 0Z" fill="currentColor" />
</svg>
Solenne Labs
</span>
<span>Studies · Archive · Contact</span>
</div>
<div className="flex items-center justify-between">
<span>Study 0712 — Afterglow</span>
<span>Move to stir the light</span>
</div>
</div>
</FluidGradientCanvas>
)
}
import { FluidGradientCanvas } from "@/components/ui/fluid-gradient-canvas"<FluidGradientCanvas
color1="#f2b48c"
color2="#4a1236"
color3="#ff4b1f"
color4="#ff9a5a"
>
<h1 className="absolute inset-0 grid place-items-center text-white">
Solenne Labs
</h1>
</FluidGradientCanvas>Two ShaderMaterial passes run every frame on a fullscreen plane. The fluid pass reads its own previous frame from a ping-ponged float render target and advects a velocity field; the cursor injects velocity along its travel path, scaled by brushSize and brushStrength, and decays via fluidDecay, trailLength, and stopDecay. The display pass generates a four-color plasma from the four color* props and offsets its lookup by the fluid velocity (distortionAmount), so the gradient ripples wherever the pointer has moved.
The renderer is sized to the container, pointer tracking is bound to the component element (never the window), and a ResizeObserver resizes the targets on layout changes. Anything passed as children renders above the canvas. When prefers-reduced-motion: reduce is set, a single static frame is rendered and the cursor interaction is disabled.
| Prop | Type | Default | Description |
|---|---|---|---|
brushSize | number | 25 | Radius of the cursor's influence on the fluid. |
brushStrength | number | 0.5 | How forcefully the cursor injects velocity. |
distortionAmount | number | 2.5 | How much the fluid velocity warps the gradient lookup. |
fluidDecay | number | 0.98 | Per-frame velocity decay (lower = shorter wake). |
trailLength | number | 0.8 | Persistence of the velocity trail. |
stopDecay | number | 0.85 | Extra decay applied near a stationary cursor. |
color1–color4 | string | afterglow | The four hex colors blended into the gradient. |
colorIntensity | number | 1 | Output color multiplier. |
softness | number | 1 | Flattens the gradient mixers toward an even blend. |
className | string | — | Extra classes on the canvas container. |