Camera & Navigation
Loading terrain…
The Alps start tilted and turned. Drag to move; Ctrl+drag or right-drag changes tilt and bearing. Wheel zoom is disabled in these article examples; try it in the maps workbench.
Gestures
Section titled “Gestures”const map = createGlyphMap(host, { view, projection, controls: { drag: true, wheel: true, tilt: true }, tilt: 55, bearing: 35,});All three control flags default to true. drag controls pan/orbit, wheel controls every zoom gesture, and tilt controls pitch and bearing independently of dragging.
| Input | Action |
|---|---|
| Drag / one finger | Pan a sheet; orbit a globe |
| Wheel / two-finger pinch | Zoom |
| Ctrl+drag / right-drag | Vertical: tilt; horizontal: bearing |
| Two-finger twist | Bearing |
| Two fingers moving vertically | Tilt |
| Double-tap / two-finger tap | Zoom in / out |
| Double-tap, hold, drag | One-handed zoom; down zooms in |
| Click | click event; lngLat is null off-surface |
Touch pinch and twist combine; a recognised tilt stays exclusive until release. Disable all controls to let touch gestures scroll the article through the map.
View and limits
Section titled “View and limits”map.setView({ center: [-58.38, -34.6], span: 0.06 });map.fitBounds({ west: 5.9, east: 10.5, south: 45.8, north: 47.8 });const view = map.getView();const maxSpan = map.getMaxSpan();centeris[longitude, latitude];spanis degrees across the grid.minSpandefaults to0.001degrees.- A sheet’s
getMaxSpan()keeps the viewport covered; its ceiling changes with shape, tilt, bearing, projection, and centre. - A globe’s maximum is its projection domain width.
- Explicit
maxSpandisables the sheet cover limit and pan clamp, allowing margins.
Tilt and bearing
Section titled “Tilt and bearing”map.setTilt(55);map.setBearing(137);const pose = [map.getTilt(), map.getBearing(), map.getMaxTilt()];tilt pitches around the surface point at the view centre. Sheets default to 40 degrees; globes to 0. getTilt() reports the applied, clamped value; zooming back in restores a previously limited request.
The pivot uses the drawn ground: the same triangle-sampled, elevation-windowed terrain used to plant features, including exaggeration. A supplied groundElevation wins; without ground, the pivot stays at the datum. Terrain arriving later re-anchors before its first render and preserves the geographic centre and shared URL. Surrounding content can shift as the new relief appears. map.project(map.getView().center) lands at the centre of the grid at every pitch and span (within a cell with snapPan). unproject() inverts that same ground surface; a local solve can return null where it has no answer.
getMaxTilt() is 85 degrees on sheets; globes use a scale-dependent horizon limit capped at 85. Read it after zooming. bearing defaults to 0 (north up); 90 puts east up. getBearing() normalizes to [0, 360).
Flights
Section titled “Flights”await map.flyTo({ center: [-58.38, -34.6], span: 0.06 }, { durationMs: 1200 });await map.flyTo({ bounds: { west: 5.9, east: 10.5, south: 45.8, north: 47.8 } });await map.idle();const text = map.scene.output.textContent;A target uses centre/span or bounds, never both. durationMs: 0 jumps immediately; bow: 1 disables the mid-flight zoom-out. Call idle() after a mutation to await tiles, geometry, motion, and transitions before reading output. It has no timeout.
Change projections with setProjection.
Street-level walk mode
Section titled “Street-level walk mode”await map.flyTo({ center: [-58.3816, -34.6037], span: 0.01 });await map.idle();map.setWalk({ eyeHeight: 1.7, far: 600 });const walk = map.getWalk();map.setWalk(null); // restore the map viewMount OSM streets and buildings first. Walk mode requires an orbit projection such as glyphMapGlobe; sheets throw RangeError. Enter through the handle, not construction options. Entry sets span from far; the application should enforce the recommended maximum entry span of 0.05 degrees.
| Option | Default |
|---|---|
eyeHeight | 1.7 m |
fov | 56 degrees horizontal |
near / far | 0.5 / 600 m |
speed | 6 m/s |
maxPitch | 84 degrees from horizontal |
collision / sky | true / true |
- WASD/arrows move; Shift runs ×3; hold G to pass through buildings.
- Mouse pointer lock looks; drag is the fallback. Esc releases lock; wheel does nothing.
- Collision uses
fill-extrusionfootprints; fills remain walkable. - The sky requires
solidmode;sky: falseremoves it. - Calling
setWalkagain reconfigures;setWalk(null)restores the saved view, tilt, bearing, and camera.
Whole-cell pans
Section titled “Whole-cell pans”createGlyphMap({ ..., snapPan: true }) holds tiny pans on one rendered
cell lattice. Flat maps translate by whole output cells; globes quantize
rotation on a local tangent lattice, so shapes near the limb can still change.
The camera translation is exact on flat maps. The renderer’s screen-anchored
shading dither can still change terrain glyphs during a whole-cell step.
The held centre (getView() and shared links) stays exact. Zoom, tilt,
bearing and grid changes start a new lattice without snapping that change.
Walking bypasses snapping. Use map.setSnapPan(boolean) to toggle it.
The /maps View folder enables Snap pan by default and saves the choice
in shared links. Omission in the package keeps continuous pans.
Experimental compositor pan
Section titled “Experimental compositor pan”createGlyphMap({ ..., compositorPan: true }) renders a quarter-view margin
of extra cells and translates the text container during mouse or one-finger
pans and inertial glide. Cell size stays fixed; base, detail, and stroke-overlay
text move together. Labels, markers, and other DOM hotspots hide until
settle. Compass and minimap UI remain fixed.
The cache refreshes at 80% of either margin. Globe pans approximate rotation with the screen displacement of the cached view centre and refresh after 2° of rotation, so features away from the centre can distort briefly. Refreshes can change screen-anchored shading dither. Tile arrivals may force earlier renders; unloaded tiles are not prefetched just for the extra margin.
Release and glide rest restore the normal grid and render the actual view
(with its existing snapPan lattice). Zoom, tilt, bearing, projection, resize,
and font changes invalidate the cache. Walking bypasses it. With this option
on, scene.setInteracting does not downscale the text.
Use map.setCompositorPan(boolean) and map.getCompositorPan() at runtime.
The package defaults off; /maps defaults Compositor pan on in the View
folder and preserves the toggle in shared links.