See SetTimeOfDayOptions; only map is required.
An Atmosphere handle controlling the scene's sun.
Call this after the map's load event so the style is ready. Geolocation denial is
handled gracefully — location: 'geolocate' simply stays on map-center and never rejects.
The facade captures the map's pre-atmosphere light/sky and restores them on
Atmosphere.dispose / setEnabled(false).
Propagates from MapLibre's setLight / setSky if called before the map's style
is ready (the initial paint drives them directly). Call inside map.on('load', …).
import * as maplibregl from 'maplibre-gl';
import { prepareMapLibre, setTimeOfDay, Tiles3DMeshLayer } from '@bitruvius/sdk-maplibre';
await prepareMapLibre(maplibregl); // v6: wires the worker module · v5: no-op
const map = new maplibregl.Map({ container: 'map', style, pitch: 60 });
const city = new Tiles3DMeshLayer({ id: 'city', url });
map.on('load', () => {
map.addLayer(city);
const atmo = setTimeOfDay({
map,
date: new Date('2026-06-21T17:00:00Z'),
location: 'map-center', // follows the camera; or [lng, lat] / 'geolocate'
syncMapLibreLight: true, // light the basemap + extrusions
basemapLayerId: 'satellite',
layers: [city],
});
atmo.animate({ rate: 1800 }); // time-lapse the whole day
});
computeSunState for the underlying calculation, and GeoSunSystem for the lower-level fan-out if you prefer to wire controllers by hand.
Wire a geographically-accurate sun to a MapLibre map in one call — the primary entry point of
@bitruvius/sdk-maplibre. Computes one SunState from the date + location and fans it out to MapLibre's light/sky (the visual sync), an optional hillshade layer, an optional raster basemap, and any Bitruvius 3D layers you pass; then returns an Atmosphere handle to drive the date, location, enable state, and a day time-lapse.