Surface study no. 04
A studio for identities that move. We cast brands in liquid metal, then let them settle into something you can hold.
A live WebGL gradient of light split through a prism: a thin white beam enters from one side and leaves as a few soft fans of dispersed color, each running its palette edge to edge, with caustic streaks flowing along the beams, a slow sway and a bloom around the prism. The fans can use a custom palette, a physical rainbow or any mix of the two; dark bases glow, light bases take the light as a tint. Colors, spectrum mix, base color, beam count, spread, angle, prism position, bloom, sharpness, caustics, the white beam, speed, saturation and film grain are all props, and a new palette fades through over a set time; the prism eases a little toward the cursor. On load the beams reach out of the flat base color over 2.4 seconds. It adapts its resolution to the device, pauses offscreen, holds a still frame for reduced motion and falls back to a CSS color fan without WebGL.
The import and the props worth knowing about, in one place.
import { PrismGradient } from "@/components/beste/component/prism-gradient";
// As a layer behind content
<section className="relative min-h-[40rem]">
<PrismGradient className="absolute inset-0" />
<div className="relative">...</div>
</section>
// A pure rainbow fanning upward on a warm paper base
<PrismGradient
className="min-h-[32rem]"
baseColor="#f4efe6"
spectrum={1} // a physical rainbow
beams={1}
spread={0.8}
angle={70}
sourceX={0.5}
sourceY={0.15}
/>Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
colors | string[] | — | Palette the beams spread through, 1 to 6. Any CSS color, tokens included. |
spectrum | number | — | Mix between the palette (0) and a physical rainbow (1). |
baseColor | string | — | Color behind the light. Dark bases glow; light bases take the light as a tint. |
beams | number | — | Number of dispersed beams leaving the prism, 1 to 5. |
spread | number | — | How wide each beam fans its colors, 0 (a thin line) to 1 (a broad fan). |
angle | number | — | Direction the beams travel, in degrees (0 = right, 90 = up). |
sourceX | number | — | Where the prism sits across the frame, 0 to 1. |
sourceY | number | — | Where the prism sits up the frame, 0 (bottom) to 1 (top). |
bloom | number | — | Soft glow around the beams and the prism, 0 to 1. |
sharpness | number | — | How crisp the beam edges are, 0 (soft) to 1 (sharp). |
caustics | number | — | Caustic streaks running along the beams, 0 to 1. |
whiteBeam | number | — | The white beam entering the prism from the other side, 0 (off) to 1. |
speed | number | — | How fast the beams sway and the streaks flow, 0 (still) to 3. |
saturation | number | — | Color intensity, 0 (grey) to 2 (vivid). 1 keeps the colors as given. |
grain | number | — | Film grain over the light, 0 to 1. |
grainSize | number | — | Size of one grain in CSS pixels, 1 to 4. |
grainMotion | boolean | — | Let the grain flicker like film instead of holding still. |
transition | number | — | Seconds a change of `colors` or `baseColor` takes to fade through. 0 swaps at once. |
seed | number | — | Picks a different sway and streak pattern. |
interactive | boolean | — | The prism eases a little toward the cursor. |
paused | boolean | — | Hold the light still. |
className | string | — | |
children | ReactNode | — |