Contours from an actual height field.
The canvas builds a grid of elevation values every frame. Elevation comes from broad simplex noise, smaller detail and a folded ridge. A Gaussian-shaped local term is added around the pointer, which is why moving over the hero raises a temporary hill instead of merely moving an ornament. The transect has one additional, dated wet-swale term: changing its field sheet shifts a real contour rather than swapping an illustration.
1SampleNoise + ridge + cursor elevation
2ClassifyEach cell is compared to seven levels
3DrawCrossing edges become contour segments
function terrainAt(u, v, time, record) {
const t = time * .36 + options.phase + (record ? record.phase : 0);
const broad = simplex.noise2D(u * 2.05 + t * .055, v * 2.05 - t * .035);
const detail = simplex.noise2D(u * 5.4 - t * .03, v * 5.4 + t * .045) * .28;
const fold = Math.sin((u * 4.3 + v * 1.25) + broad * 1.8) * .16;
const dx = u - state.pointerX, dy = v - state.pointerY;
const cursorHill = options.interactive
? state.influence * Math.exp(-(dx * dx + dy * dy) / .008) * .86 : 0;
const wetSwale = record ? record.water * (Math.exp(-(((u - .58) ** 2) / .035 + ((v - .72) ** 2) / .016))
+ .55 * Math.exp(-(((u - .22) ** 2) / .08 + ((v - .49) ** 2) / .03))) : 0;
return broad * .7 + detail + fold + cursorHill + wetSwale;
}
const contourPairs = [null, [0, 3], [0, 1], [3, 1], [1, 2], [0, 3, 1, 2], [0, 2], [3, 2], [2, 3], [0, 2], [0, 1, 2, 3], [1, 2], [1, 3], [0, 1], [0, 3]];
const mask = (a >= level ? 1 : 0) | (b >= level ? 2 : 0)
| (c >= level ? 4 : 0) | (d >= level ? 8 : 0);
if (mask === 0 || mask === 15) continue;
const pairs = contourPairs[mask];
for (let pair = 0; pair < pairs.length; pair += 2) {
drawSegment(pairs[pair], pairs[pair + 1], px, py, cellW, cellH, a, b, c, d, level);
}
This is the exact terrain sampler and marching-squares cell setup used on both fields. The selected sheet is read once per render, then sampled across the grid. The loop is throttled to roughly 20fps, reuses edge points between cells, caps canvas DPR at 2, and stops when a field is not visible or the tab is hidden. A first static render is painted before each canvas fades in, so the terrain never arrives as a blank block.