Installation
pnpm dlx shadcn@latest add https://dithercn.dev/r/dot-map.jsonUsage
import { DotMap } from "@/components/dithercn/dot-map";
const OFFICES = [
{ at: [51.51, -0.13], label: "London" },
{ at: [35.68, 139.69], label: "Tokyo" },
] as const;
export function Offices() {
return (
<DotMap
markers={OFFICES}
arcs={[{ from: OFFICES[0].at, to: OFFICES[1].at }]}
accent="blue"
/>
);
}The map is an SVG that scales to its container's width and keeps its aspect ratio. Land comes from a 3.8 KB mask of Natural Earth's public-domain land polygons that installs with it as world-land, so nothing is fetched at runtime.
Each marker pulses and casts a dithered halo on the land around it: dense at the marker, thinning through the Bayer levels. Arcs are dotted curves with a stretch of light running along them.
Examples
Customers worldwide
Many small markers, round dots and a tight halo, between a headline and a row of stats.
Region map in a card
bounds crops the map to a region. Here, Europe, with labelled edge regions in a dashboard card.
Routes, held still
Arcs only, with faint sea dots and animate={false}.
Props
| Prop | Type | Default |
|---|---|---|
| markers Locations to mark. Labels show beside the marker and are read by screen readers. | Type: { at: [lat, lon]; label?: string; color?: DitherColor }[] | Default [] |
| arcs Dotted curves between places. | Type: { from: [lat, lon]; to: [lat, lon]; color?: DitherColor }[] | Default [] |
| color Colour of the land dots. | Type: DitherColor | Default "grey" |
| accent Colour of markers, halos and arcs that don't set their own. | Type: DitherColor | Default "ink" |
| columns Dots across the full width. | Type: number | Default 160 |
| shape Dot shape. | Type: "square" | "round" | Default "square" |
| halo Radius in degrees of each marker's dithered glow on the land. 0 turns it off. | Type: number | Default 14 |
| ocean Share of sea cells with a faint dot, 0 to 1. | Type: number | Default 0 |
| bounds The region to draw, in degrees. | Type: { north; south; west; east } | Default 78°N to 56°S, all longitudes |
| animate Pulse the markers and run light along the arcs. | Type: boolean | Default true |
| title Accessible name. Marker labels are appended to it. | Type: string | Default "World map" |
Notes
- The map is one image to assistive technology, named by
titleplus the marker labels. - Pulses and running arcs are CSS animations. With reduced motion they are hidden and the map is still.
- Pass
markersandarcsas constants or memoised arrays: the dot paths are rebuilt when they change. Land cells are cached per grid size. - Land data: Natural Earth 1:50m land, public domain, rasterised to 0.75° cells.