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 field of out-of-focus light: soft discs of varying size drift upward over a gentle wash of the palette, each with the soft interior and slightly brighter rim of real lens bokeh, near discs larger and brighter than far ones. The discs can take the polygon shape of the aperture blades, the focus goes from dreamy to crisp, and the depth layers shift with parallax toward the cursor. Colors, background, count, size, focus, aperture, blades, brightness, wash, speed, depth, saturation and film grain are all props, and a new palette fades through over a set time. It grows softly out of its background on load, adapts its resolution to the device, pauses offscreen, holds a still frame for reduced motion and falls back to soft CSS circles without WebGL.
The import and the props worth knowing about, in one place.
import { BokehGradient } from "@/components/beste/component/bokeh-gradient";
// As a layer behind content
<section className="relative min-h-[40rem]">
<BokehGradient className="absolute inset-0" />
<div className="relative">...</div>
</section>
// Crisp hexagonal city lights
<BokehGradient
className="min-h-[32rem]"
colors={["#ffd28a", "#ff8a5c", "#f6f1e7"]}
backgroundColor="#120d0a"
focus={0.8}
aperture={1} // the polygon of the aperture blades
blades={6}
count={32}
/>Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
colors | string[] | — | Colors of the light discs, 1 to 6. Any CSS color, tokens included. |
backgroundColor | string | — | The dark (or light) ground behind the lights. |
count | number | — | Number of light discs, 4 to 40. |
size | number | — | Size of the discs, 0.5 to 2. |
focus | number | — | Lens focus, 0 (dreamy soft edges) to 1 (crisp discs with a bright rim). |
aperture | number | — | Disc shape, 0 (round) to 1 (the polygon of the aperture blades). |
blades | number | — | Aperture blades when `aperture` is above 0, 5 to 9. |
brightness | number | — | How bright the lights glow, 0 to 1. |
wash | number | — | A soft wash of the palette over the ground, 0 (none) to 1. |
speed | number | — | How fast the lights drift, 0 (still) to 3. |
depth | number | — | Parallax between near and far lights, 0 (flat) to 1 (deep). |
saturation | number | — | Color intensity, 0 (grey) to 2 (vivid). |
grain | number | — | Film grain over the frame, 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 `backgroundColor` takes to fade through. 0 swaps at once. |
seed | number | — | Picks a different scatter of lights. |
interactive | boolean | — | The layers shift with parallax toward the cursor. |
paused | boolean | — | Hold the lights still. |
className | string | — | |
children | ReactNode | — |