Backgrounds✨ Premium

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.

Canvas 2DContour LinesPointer

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

🎈

① Hiking, trail-running or mountain-guiding site

WhenThe world is one of maps and relief, and a summit photo has already been used three times higher up the page.
WhyThe contour line is the graphic sign of terrain: it says "mountain" without showing one, so it never competes with the photography. The slow drift suggests a flyover rather than travel.
SettingsUse the sable palette for a paper-map feel, and numBands at 16 for rougher relief. Lower HILL_AMP to 0.10 if the cursor interaction pulls too much attention.
🎊

② Header for a mapping, geodata or GIS tool

WhenA technical product with a dense grey interface, whose marketing page must signal "mapping" within a second.
WhyThe pattern reads as cartographic immediately to the intended audience, and it stays sober: thin lines on a dark ground, with no loud colour to date the page.
SettingsUse the slate palette and FREQ at 5.0 for a tighter mesh suggesting a large scale. Turn the cursor hill off (HILL_AMP = 0) if the background sits behind a clickable interface.

③ Chapter divider in a long-form article

WhenA feature needs visual breathing room between sections without breaking reading rhythm with a full-width image.
WhyA 200 px band is enough: the contour lines form a readable pattern there, and the drift is slow enough not to catch the eye while the neighbouring paragraph is being read.
SettingsReduce the container height and raise STRIDE to 3: on a small surface the loss of detail is invisible and the CPU cost halves.

How it works

Value noise is summed over 4 octaves (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: reduce the 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 a role="img" with a descriptive aria-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.

Chrome 60+✓ Full
Edge 79+✓ Full
Firefox 55+✓ Full
Safari 11+✓ Full
Safari iOS 11+✓ Full — keep STRIDE at 2 or 3
Chrome Android 60+✓ Full

Without 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):

index.html — structure
<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>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
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

Because the real constraint here is robustness, not raw power. A WebGL shader would be faster, but it adds a graphics context to manage, context-loss cases to handle, and silent failure on machines where acceleration is disabled. With STRIDE at 2, the 2D canvas comfortably holds 60 frames per second on an ordinary laptop, and it works everywhere, without exception.
Not perceptibly. The field drifts diagonally through noise defined over the whole plane: it does not loop. In practice you would have to leave the page open for hours to re-enter a region already seen, and the terrain would have changed character by then anyway.
Yes, on two conditions. Keep the vignette: it darkens the edges and steadies the background behind centred text. And avoid placing copy where the index contours bunch up — they are the only lines bright enough to interfere. When in doubt, drop the canvas opacity to 0.6: the pattern still reads as texture and stops competing with the text.