crucıble

Swell

Sprung wave lattice: depth-graded rows of smooth lines ride an orbital noise field with woven coherence while a slow autonomous swell front rolls through every ~8s. Cursor swipes inject velocity impulses along the travel direction, proportional to cursor speed, then spring home on damped Hooke springs with a tanh soft-clip on stretch. Deep-sea steel default. Canvas 2D, seeded, offscreen-paused, DPR-clamped with device-pixel-aligned strokes, reduced-motion-safe (crest frozen mid-roll).

canvasfree

Installation

CLI

npx shadcn@latest add @crucible/swell

Props

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal""horizontal" — rows of swell lines, depth rising toward the bottom of the frame (an open-sea read). "vertical" — hanging curtains of line with seeded depth layers.
gap{ x: number; y: number }{ x: 28, y: 26 }Lattice spacing in CSS px: x = horizontal spacing, y = vertical spacing. For horizontal orientation y sets the row gap and x the sample step along each row (vertical orientation swaps roles). Each axis clamped 8–200.
amplitudenumber16Idle wave amplitude in CSS px — how far points orbit their anchors.
speednumber1Animation-speed multiplier for drift and the swell front. 1 = default.
intensitynumber1Line brightness, 0–2.
tensionnumber150Spring stiffness pulling displaced points home (per s²). Higher = faster, tighter snap-back. Clamped 1–600.
frictionnumber0.93Spring velocity retention per frame at 60fps, 0–0.999 (applied frame-rate-independently). Lower = deader, higher = wobblier.
maxStretchnumber48CSS-px displacement the cursor can stretch a point toward. Rendered through a tanh soft-clip, so stretch saturates smoothly — never a hard stop.
swellIntervalnumber8Period in seconds of the autonomous swell front — a slow pressure wave that rolls through the lattice so the field breathes with no cursor.
colors[string, string]["#31404f", "#7dd3fc"]Two tones [far, near] graded across row depth. Defaults to deep-sea steel: dim slate far rows rising to cyan-tinged near rows. Pass warm tones for a dune-wind look.
interactivebooleantrueWhen true, cursor swipes inject velocity impulses along the travel direction, proportional to smoothed cursor speed, then spring back.
seednumber1Deterministic seed for depth layout and drift phases.
dprnumber2devicePixelRatio ceiling. Clamped 1–2.
pausedbooleanfalseFreeze at a static frame with the swell front mid-roll (never flat).
Also accepts all props of React.ComponentPropsWithoutRef<"div">they pass through to the underlying element.

Honors prefers-reduced-motion with a designed static fallback, pauses offscreen and on hidden tabs, and passes className through.