Concept
Orbit the globe, pan the plane.
One set of gestures, interpreted by the active projection. On the globe a drag is a real 3D orbit around the planet; on a flat map the same drag pans a plane. The cursor stays anchored across a zoom, a flick glides with inertia, and a Mapbox-parity API drives the camera from code.
The model
The camera is projection-aware: a drag, a scroll, a pinch mean the same thing to the user, but the camera resolves them differently depending on what is on screen. The 3D globe is a true orbit camera around the planet; the seven flat projections move a 2D plane. The input layer reads the active projection each frame and routes every gesture down the matching path, so the point you grab stays under your finger whether the Earth is a sphere or a Mercator sheet.
Everything below is true of the engine today, with the one not-yet-built part — an animated fly-to — marked as roadmap.
Orbit the globe, pan the plane
Pan splits on the projection family: a flat map slides in projected metres, the globe rolls in surface degrees.
Pan the plane
Orbit the globe
Zoom toward the cursor
The point under the cursor stays put
Smooth wheel zoom
Rotate and tilt
Bearing and pitch, by drag or pinch
Inertia
Flick to glide
Projection-aware unproject
Screen pixel → geographic point
Programmatic control
A Mapbox-parity camera API
setCenter,
setZoom,
jumpTo,
panBy,
getBounds,
fitBounds — matching MapLibre
GL JS's signatures. fitBounds
fits a lon/lat box by choosing the more constraining of the
horizontal and vertical fit zooms. Every input is finite-checked and
clamped (zoom to its min/max, pitch to 0–85°), and
setMaxBounds /
setMinZoom /
setMaxZoom constrain
interactive gestures too. Drag and panBy
are device-pixel-ratio invariant — one CSS pixel of input is the
same world distance on any display.
Where it is going
Roadmap · not yet shipped
These are planned, not built. They are on the roadmap, not in the engine today:
- → Animated fly-to — smooth, eased camera
flights between views. Today
easeToandflyToexist for API parity but jump instantly to the destination; there is no transition interpolation yet. - → Azimuthal-disc unproject — screen→lon/lat for the orthographic / azimuthal-equidistant / stereographic discs is deferred (their limb is singular). Drag and pinch on those discs are already anchored via a dedicated disc inverse; the general-purpose unproject returns null for them.
Tracked in the repo ROADMAP.md ↗.
See it live
The camera is best felt, not read. Drag, scroll, and pinch the globe in the home page hero, or open the playground to orbit, pan, and zoom a real map and switch projections under the same gestures.
Specifications
See also
Problem on this page?