MynduiMyndui
0

Anatomy of the World Map

How a deterministic dot grid, a plain quadratic Bézier, and a fill-box ripple combine into a map that's identical on the server and the client.

01/04Dots, pins, one arc
Dots
static SVG grid, drawn once with currentColor
Pin
one per arc endpoint, deduped by coordinate
Arc
quadratic Bézier bow between two pins
tsx
const map = new DottedMap({ height: 60, grid: "diagonal" });const svg = map.getSVG({ radius: 0.22, color: "currentColor", shape: "circle" });
01

Dots, pins, one arc

WorldMap never fetches a map image. The land is a grid of dots generated on the fly, the arcs are two-point curves computed from the same projection that placed the dots, and none of it depends on anything that could differ between server and client.

Everything shares a single SVG coordinate space. A static grid of land dots is generated once with dotted-map and drawn with currentColor; a pin marks every arc endpoint; an arc is just a quadratic Bézier bow between two pins.

Rendering the dots with currentColor instead of baking a fixed color into the generated markup means dotColor, set on the SVG's own style.color, can restyle every dot without regenerating the grid.

DottedMap with fixed arguments always produces the exact same grid. That determinism is what lets WorldMap render this way at all: a hydration mismatch would happen the instant the server's markup differed from the client's, and there's no client-only escape hatch here — the dots are injected with dangerouslySetInnerHTML on first render, not patched in after mount.

tsx
 
const { markup, width, height, map } = React.useMemo(() => {
  const map = new DottedMap({ height: 60, grid: "diagonal" });
  // …
}, []);

map.getPin({ lat, lng }) is the same projection dotted-map used to place every dot, so an arc's endpoints land exactly on real dot positions instead of drifting from a separately-computed lat/lng-to-pixel formula:

tsx
 
const a = map.getPin({ lat: c.start.lat, lng: c.start.lng });
const b = map.getPin({ lat: c.end.lat, lng: c.end.lng });
const cx = (a.x + b.x) / 2;
const bow = Math.hypot(b.x - a.x, b.y - a.y) * 0.35;
const cy = Math.min(a.y, b.y) - bow;
// d = `M ${a.x} ${a.y} Q ${cx} ${cy} ${b.x} ${b.y}`

The control point sits above the midpoint, offset by 35% of the start-to-end distance — the farther apart two points are, the higher the arc bows, which is what keeps a short hop and a transcontinental line both reading as "an arc" instead of the long one looking almost flat.

02/04The draw-in

pathLength: { duration, delay: 0.4 + i * 0.3, ease: [0.22,1,0.36,1] }

Track
the full arc, always faintly visible
Reveal
travels start pin → end pin, then loops
tsx
initial={reduceMotion ? false : { pathLength: 0 }}animate={{ pathLength: 1 }}transition={{duration,delay: 0.4 + i * 0.3,ease: [0.22, 1, 0.36, 1],repeat: loop ? Number.POSITIVE_INFINITY : 0,repeatDelay: loop ? connections.length * 0.3 : 0,}}
02

The draw-in

Each arc animates pathLength from 0 to 1, staggered per connection so a whole map full of routes doesn't snap in all at once.

repeatDelay scales with connections.length — more arcs means a longer pause before the whole set redraws together, so the loop always reads as "the map refreshes," not "arc 1 restarts while arc 4 is still drawing."

Each arc strokes with a horizontal linear gradient instead of a flat color, so every beam visibly emerges from its start pin and dissolves into its end pin rather than terminating with a hard-edged cap:

tsx
 
<linearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="0%">
  <stop offset="0%" stopColor={lineColor} stopOpacity="0" />
  <stop offset="12%" stopColor={lineColor} stopOpacity="1" />
  <stop offset="88%" stopColor={lineColor} stopOpacity="1" />
  <stop offset="100%" stopColor={lineColor} stopOpacity="0" />
</linearGradient>
03/04The pin ripple
Pin
the static core circle, never animates
Ripple
a second circle, scale + fade, infinite
tsx
<motion.circleinitial={{ scale: 1, opacity: 0.6 }}animate={{ scale: 3, opacity: 0 }}transition={{ duration: 1.8, repeat: Number.POSITIVE_INFINITY, ease: [0.22, 1, 0.36, 1] }}style={{ transformBox: "fill-box", transformOrigin: "center" }}/>
03

The pin ripple

Every endpoint gets a second, purely decorative circle behind the solid pin — the ripple. It scales from 1 to 3 while fading from 0.6 to 0, forever, using transformBox: fill-box so it scales around its own center instead of the SVG's coordinate origin.

Without transformBox: fill-box, an SVG element's default transform origin is the coordinate (0, 0) of its nearest viewport, not its own shape — the ripple would scale away from the pin instead of growing outward from it.

04/04Result
04

The result

A deterministic dot grid, arcs projected from the same math that placed the dots, and two independent infinite loops — the draw and the ripple — that both vanish cleanly under reduced motion.

Reduced motion

Under prefers-reduced-motion, arcs render fully drawn immediately and the ripple circle isn't rendered at all — not paused, not frozen mid-animation, simply absent. The map is fully legible on first paint with nothing left looping.

tsx
 
initial={reduceMotion ? false : { pathLength: 0 }}
{!reduceMotion && <motion.circle /* ripple */ />}

Motion Score

World MapSSCompositor-only
SopacityFade / cross-fade
SpathLengthSVG pathLength reveal
Each property is graded by how the browser runs it, from S (composited off the main thread) down to F (layout thrashing); the component takes the worst. MotionScore methodology →