Track Map
A geometry-agnostic circuit map: you give it an SVG path, it colours the sectors with the flag in force and slides a marker per car round the lap.
Any outline works. Feed a GeoJSON LineString straight into pathFromPoints(coordinates) and it returns a d and a matching viewBox, with the y axis flipped so north points up. The demo outlines come from bacinger/f1-circuits on GitHub (MIT), projected and fitted by scripts/build-circuits.ts; the first point of each outline is treated as start/finish.
Markers move at constant speed between position updates: set transitionMs to the interval of your data source and every update chains into the next without a stop. On a closed path (a d ending in Z) a car crosses the line without jumping back.
pitLane takes an open d from pit entry to pit exit; a marker with inPit runs along it, its progress measured from entry to exit, and jumps between the two roads rather than sliding across the circuit. The outline dataset has no pit lanes, so the ones shown here are approximations generated by scripts/build-circuits.ts from the stretch of the lap around the line (src/lib/pit-lane.ts); Aster Park has a hand-drawn one.
onMarkerClick makes every car a button, named by its code, and dimOthers fades the cars without emphasis so the emphasised one is the car the eye follows. secondaryEmphasis on a marker is the lesser step, for cars watched next to it: the normal dot, but its code stays on a small map and dimOthers leaves it alone. A map with clickable cars exposes them, so its role becomes group rather than img; without the handler it renders exactly as before.
Check the licence of the outline, not only of the file. Circuit layouts are the intellectual property of the circuits themselves, which is also what the championship says in its own fan guidelines. The layouts shown here are unofficial and this project is not affiliated with any series, circuit, or team. Aster Park is an invented circuit and safe to use anywhere.
Preview
- EVO at 0% of the lap
- MSO at 11% of the lap
- TRE at 22% of the lap
- NVA at 33% of the lap
- AQU at 44% of the lap
- SDA at 55% of the lap
Click a car to pick it out and dim the rest; click it again to let it go.
Playground
The 2026 calendar, from public GeoJSON outlines, plus the invented Aster Park.
Flag over the first third of the lap.
Flag over the middle third of the lap.
Flag over the last third of the lap.
How many markers to place on the track.
Label each marker with its driver code.
Give the car behind the emphasised one a lesser emphasis.
Marker and label scale. The map always fills its container.
Send the cars round the lap.
Installation
Register the boxbox namespace once per project:
bunx shadcn@latest registry add @boxbox=https://react-boxbox.vercel.app/r/{name}.jsonThen add the component:
bunx shadcn@latest add @boxbox/track-map
Props
| Name | Type | Default | Description |
|---|---|---|---|
| circuit | 'Aster Park' | 'Melbourne' | 'Shanghai' | 'Suzuka' | 'Sakhir' | 'Jeddah' | 'Miami' | 'Montreal' | 'Monaco' | 'Barcelona' | 'Spielberg' | 'Silverstone' | 'Spa Francorchamps' | 'Budapest' | 'Zandvoort' | 'Monza' | 'Madrid' | 'Baku' | 'Sepang' | 'Singapore' | 'Austin' | 'Mexico City' | 'Sao Paulo' | 'Las Vegas' | 'Lusail' | 'Yas Marina' | Silverstone | The 2026 calendar, from public GeoJSON outlines, plus the invented Aster Park. |
| sector1 | 'none' | 'green' | 'yellow' | 'double-yellow' | 'red' | 'sc' | 'vsc' | 'chequered' | green | Flag over the first third of the lap. |
| sector2 | 'none' | 'green' | 'yellow' | 'double-yellow' | 'red' | 'sc' | 'vsc' | 'chequered' | yellow | Flag over the middle third of the lap. |
| sector3 | 'none' | 'green' | 'yellow' | 'double-yellow' | 'red' | 'sc' | 'vsc' | 'chequered' | green | Flag over the last third of the lap. |
| cars | number | 6 | How many markers to place on the track. |
| showCodes | boolean | true | Label each marker with its driver code. |
| secondCar | boolean | false | Give the car behind the emphasised one a lesser emphasis. |
| size | 'sm' | 'md' | 'lg' | md | Marker and label scale. The map always fills its container. |
| animate | boolean | true | Send the cars round the lap. |
Dependencies
No additional dependencies.