Topographic Drift
A topographic map drifting slowly, drawn pixel by pixel: a 4-octave fBm noise field sliced into 12 elevation bands, of which only the boundaries are kept. The cursor raises a hill under the terrain, and the contour lines tighten around it just as they would on a real survey map.
You'll get access to the interactive demo with a free account.
This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Backgrounds has 50 effects, including 6 free. Explore the category →
3 usage examples
How it works
fbm) to produce a continuous elevation field between 0 and 1. Every canvas pixel samples that field at its own position, offset by a value advancing at 7.2 × 10⁻⁵ units per millisecond: that is the drift.
Elevation is multiplied by the band count (12); only pixels whose fractional part falls under LINE_THR (0.091) are kept. In other words: only the boundaries between steps are drawn — the contour lines. Every fourth band is stroked in a lighter tone; those are the index contours.
When the pointer enters the scene, a quadratic dome of 190 px radius is added to the field (HILL_AMP = 0.20). Because the lines follow band boundaries, that bump naturally makes them tighten into concentric rings. The cursor position is smoothed at 4.8 % per frame, which removes any jerk.Accessibility
- Under
prefers-reduced-motion: reducethe drift stops and the cursor hill is no longer computed: the terrain stays on screen, crisp and still. The background keeps its decorative role without imposing motion. - The canvas carries
aria-hidden="true"and the container arole="img"with a descriptivearia-label: a screen reader announces an image and what it is, never a stream of pixels. - No information is carried by this background alone. The contour lines are decor, not data: nothing a visitor needs to understand is encoded in them.
- All three palettes pair a very dark ground (under 8 % luminance) with light lines. Still check contrast if you place text: the index contours in the "slate" palette reach a light grey that can compete with secondary copy.
Browser compatibility
Canvas 2D with createImageData and direct writes into the pixel array, plus requestAnimationFrame and matchMedia. The noise is computed in plain JavaScript — no library, no WebGL, no shader.
STRIDE at 2 or 3Without JavaScript the canvas stays empty: give .tpd-scene a background colour so the section keeps its shape. The CSS vignette renders in every case and is enough to suggest depth.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<div class="tpd-scene" id="tpdScene"
role="img"
aria-label="Animated topographic background — drifting contour lines">
<!-- The canvas carries the whole render; it is decorative, hence aria-hidden -->
<canvas class="tpd-canvas" id="tpdCanvas" aria-hidden="true"></canvas>
<!-- CSS vignette: darkens the edges so centred text stays readable -->
<div class="tpd-vignette" aria-hidden="true"></div>
</div>
Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
numBands — number of elevation steps |
12 | Contour density. 6 gives soft, airy relief; 24 a very tight map. Past 30 the lines touch and the pattern collapses back into a flat fill. |
FREQ — noise field frequency |
3.6 | Terrain scale. A low value (1.5) gives a few large massifs; a high one (7) a rugged, repetitive landscape. This is the setting that most changes the background's identity. |
DRIFT — drift speed |
7.2e-5 per ms | How fast the field advances. Double it for a noticeable flyover, divide by five for motion you only register when returning to the page. |
HILL_AMP and HILL_R — cursor hill |
0.20 and 190 px | Height and radius of the dome following the pointer. HILL_AMP at 0 disables the interaction; at 0.40 the hill becomes a peak ringed by very tight contours. |
MAJOR_N — index contour interval |
4 | Every Nth band is stroked lighter and more opaque. 5 or 10 are the usual cartographic conventions; 2 gives a striped look, more graphic than realistic. |
STRIDE — pixel block size |
2 | The performance lever. The renderer computes one pixel out of STRIDE then fills the block. Going from 2 to 3 more than halves the cost for a barely visible loss of sharpness. |
PAL — palettes |
slate, teal, sable | Each palette supplies three colours: ground, minor line, index contour. Adding an entry is all it takes to build your own theme without touching the engine. |
FAQ
STRIDE at 2, the 2D canvas comfortably holds 60 frames per second on an ordinary laptop, and it works everywhere, without exception.