For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. The dithercn agent skill, for building any dither on the engine, is at /.well-known/agent-skills/dithercn/SKILL.md.
dithercn

Dither globe

A rotating dithered globe with a lit terminator, pulsing markers and arcs, for global sections of a landing page.

Controls
Land
Accent
Speed6°/s
Tilt18°
Cell2px
Arcs
Animate

Installation

pnpm dlx shadcn@latest add https://dithercn.dev/r/dither-globe.json

Usage

import { DitherGlobe } from "@/components/dithercn/dither-globe";
 
const LONDON = [51.51, -0.13] as const;
const TOKYO = [35.68, 139.69] as const;
 
export function Global() {
  return (
    <DitherGlobe
      markers={[{ at: LONDON }, { at: TOKYO }]}
      arcs={[{ from: LONDON, to: TOKYO }]}
      className="aspect-square w-full max-w-md"
    />
  );
}

The globe is drawn on a 2D canvas at dither-cell resolution: every cell on the sphere gets a tone from the land mask and the light, then an ordered threshold decides whether it's inked. Land is bright on the day side and fades to a sparse grid past the terminator; the sea is a faint dither that thickens towards the rim. It uses no WebGL context, so it doesn't count against the page's shader budget.

The globe stays round and centred in its box and takes 84% of the shorter side. Make the box larger than its section and offset it to show only the top of the globe, as in the first example.

Visitors can turn the globe. Dragging sideways spins it and dragging up or down tilts it, with the land staying under the pointer. Let go mid-drag and it coasts to a stop, then picks its idle spin back up. On phones, a horizontal swipe turns it and a vertical swipe still scrolls the page. When it has keyboard focus, the arrow keys turn it. Set draggable={false} for a globe that should only spin on its own.

Land comes from the shared world-land mask (Natural Earth, public domain), installed with the component. Nothing is fetched at runtime.

Examples

Horizon behind a headline

A globe 150% of the section's width, pushed below the bottom edge so only its lit top shows.

Beside copy

A square globe in a two-column section. Drag it to spin.

Turned to one place, in a card

speed={0} and start at the marker's longitude hold one region in view while the marker keeps pulsing.

Props

PropTypeDefault
color

Colour of the land, sea and atmosphere.

Type: DitherColorDefault "ink"
accent

Colour of markers and arcs that don't set their own.

Type: DitherColorDefault "orange"
markers

Pulsing locations. Markers on the far side are hidden.

Type: { at: [lat, lon]; color?: DitherColor }[]Default []
arcs

Great-circle arcs lifted off the surface, with a stretch of light running along them.

Type: { from: [lat, lon]; to: [lat, lon]; color?: DitherColor }[]Default []
speed

Degrees of rotation per second. Negative spins the other way.

Type: numberDefault 6
start

Longitude facing the viewer at the start, in degrees.

Type: numberDefault 10
tilt

How far the north pole leans towards the viewer, in degrees.

Type: numberDefault 18
light

Where the light comes from, in degrees clockwise from the top.

Type: numberDefault 300
ocean

Brightness of the sea on the lit side, 0 to 1.

Type: numberDefault 0.18
atmosphere

A thin dithered glow around the lit rim.

Type: booleanDefault true
draggable

Drag or use the arrow keys to turn and tilt the globe. It coasts after a drag, then eases back into its idle spin.

Type: booleanDefault true
cell

Size of one dither cell in CSS pixels.

Type: numberDefault 2
matrix

Threshold matrix.

Type: "bayer2" | "bayer4" | "bayer8" | "blue-noise"Default "bayer4"
animate

Spin and pulse. false draws one still frame.

Type: booleanDefault true

Notes

  • A draggable globe is focusable and announced as an image labelled "Globe. Drag it or use the arrow keys to turn it." Pass your own aria-label to say what it shows. With draggable={false} it's decorative and hidden from assistive technology, so say what it shows in the copy next to it.
  • With reduced motion turned on, it draws one still frame. Dragging and the arrow keys still turn it, without the coasting.
  • It pauses when scrolled out of view or when the tab is hidden. A 600px globe at 2px cells is about 70,000 cells per frame at 30 fps, well within budget on a phone; raise cell for very large globes.