← LONGWAVE THE GUIDE · how it was built
Design showcase · build notes

Rendering a planet from procedural data.

Longwave looks like an earth-observation console, but it is one HTML file, one stylesheet and one ES-module — no framework, no build step, and not one image asset. Two techniques carry the whole thing: a three.js data globe generated entirely from math, and a canvas warming-stripes chart. Here is how both work.

THE IDEAMake the abstract feel measured.

Climate data is easy to make dramatic and hard to make credible. The brief was the opposite of a doom poster: an instrument. So the interface borrows the grammar of shipped tools — a floating layer switcher, a legend with a color scale, a time-scrubber, metric tiles with deltas — studied from Apple Weather, The Weather Channel, Flighty, Felt and a few carbon dashboards. The visuals on top are invented; the interaction patterns are the ones analysts already trust.

Everything reduces to one sentence the hero states plainly: the planet is a time series — read it. The globe is the map; the stripes are the series; the layer panel decides which sensor you are reading through.

#07090d bg #e6ebf0 ink #3aa0ff cool #ff9e2c amber #ff5e3a hot

THE STACKVanilla, with three.js pulled lazily.

SIGNATURE #1The procedural data globe.

There is no texture map anywhere. The continents are faked with a sum of Gaussian "blobs" placed at real continent centroids. For any direction on the sphere, landness() returns how land-like it is, and that single function seeds the dot-field, the heat nodes and the SVG fallback alike:

function landness(dir){
  let m = 0;
  for (const [lat, lon] of CONTINENTS){
    const p = ll(lat, lon);                 // centroid → unit vector
    const d = p.x*dir.x + p.y*dir.y + p.z*dir.z;
    const ang = Math.acos(clamp(d,-1,1));   // angular distance
    m = Math.max(m, Math.exp(-(ang/0.34)**2));
  }
  return m;                                 // > 0.34 ≈ land
}

A ~3,200-point Fibonacci sphere becomes the globe: land directions get bright steel dots, ocean gets a sparse dim grid, all drawn in a single THREE.Points draw call with additive blending so they glow on the near-black. A fresnel shader on a slightly larger back-side sphere gives the atmosphere rim.

Each layer's heat nodes are scattered around seed regions (industrial cores for emissions, the poles for ice) and colored by a shared diverging ramp. The strongest nodes throw arcs — quadratic béziers lifted off the surface with a glowing sprite travelling along curve.getPoint(t) — and expanding rings oriented tangent to the surface. Toggling a layer card just flips obj.visible and re-points the legend:

globeApi.setLayers([...enabled], focus);   // one method drives the render
// auto-rotate + drag-inertia, dpr capped at 2, RAF paused on tab-hide,
// geometries/materials tracked and disposed on pagehide.

SIGNATURE #2The warming stripes.

The 1980–2024 record is generated deterministically — a linear warming trend plus ENSO wiggles, with El Niño spikes and volcanic dips nudged in and 2024 pinned to the real-world headline of +1.28 °C. Each year is one full-height bar colored by the same ramp the globe uses, so the legend reads across both visualisations:

const t = (anomaly - AMIN) / (AMAX - AMIN);
ctx.fillStyle = rgb(ramp(t));              // cool → amber → hot
ctx.fillRect(x, 0, barWidth, H);

The bars draw in left-to-right the first time the chart scrolls into view. A pointer moving over the canvas — or the range scrubber below it — snaps to a year, moves the cursor, outlines that stripe and updates the big readout with the year, anomaly and a short note. Press Play trend and it walks 1980 → 2024 on a timer.

DETAILS THAT MATTERThe unglamorous 20%.

SHIP ITGitHub Pages in three commands.

Every path is relative and there is no build, so deploying is just:

gh repo create bswxyz/longwave-climate --public --source . --push
gh api --method POST /repos/bswxyz/longwave-climate/pages \
  -f 'source[branch]=main' -f 'source[path]=/'
# live at https://bswxyz.github.io/longwave-climate/ in ~1–2 min

A .nojekyll file stops Pages from touching the folder structure. That's the whole deploy.


Longwave is a design-showcase concept — the sensors, datasets and numbers are synthetic and illustrative, not a live satellite feed or backend. See the repository README for the full demo-vs-real map.

← Back to Longwave