Living contour lines, like a map of a terrain that slowly breathes. A hill rises under the cursor and a click sends a wave across.
Installation
Usage
import { TopographyBackground } from '@/components/animate-ui/backgrounds/topography';
export function Hero() {
return (
<section className="relative h-[480px] overflow-hidden">
<TopographyBackground className="absolute inset-0 text-neutral-500" />
</section>
);
}Animation
- The terrain is a field of gradient noise drawn as contour lines, like a topographic map: every fifth line is an index contour, thicker and brighter. The noise drifts slowly through time (
speed), so the relief keeps reshaping itself. - On mount, the relief rises from flat ground in 1.8s on an ease-out: the lines bloom out from the middle level.
- Under the cursor, a peak rises on a spring and follows it (
transition), its rings tightening towards the summit (peak). Leaving the container lets it sink back. - A click (or a tap) drops a wave: a crest and a trough travel out from the point in 2.6s, bunching the lines as they pass, and fade away.
- The lines take the container's text color, or
lineColor. They're drawn with WebGL, pixel by pixel on the GPU (at most twice the device pixel ratio): no grid, so they glide without stepping and redraw on every frame, even at 120Hz and more. Where WebGL is missing, a canvas draws them as smooth curves instead. - The loop pauses off screen and while the tab is hidden.
- Under reduced motion, the terrain is a still map: no drift, no peak, no wave.
API Reference
TopographyBackground
| Prop | Type | Default |
|---|---|---|
lineColor? | string | - |
levels? | number | 16 |
speed? | number | 1 |
scale? | number | 1 |
peak? | number | 1 |
interactive? | boolean | true |
transition? | SpringOptions | { stiffness: 120, damping: 20 } |
...props? | React.ComponentProps<'div'> | - |