# Animated Background A browser-based animated desktop background: a WebGL flight scene over real terrain, driven by the real sun, moon, stars and live weather. Designed to be dropped into an iframe or kiosk browser and left running. ## Features - **WebGL flight scene** (`vendor/clouds3d.js`): a 3D terrain mesh built from real elevation data (Copernicus DEM), a raymarched volumetric cloud deck, and a figure-eight flight path around the configured location with a vertical bob inside the 15-35 km flight band. - **One physical light model** shared by sky, clouds, contrails, aircraft and ground: direct beam through a Kasten-Young air mass with Rayleigh, ozone and aerosol extinction, diffuse skylight, moonlight, a starlight floor and aerial perspective. Sun and moon come from the real positions (SunCalc) for `CONFIG.location`; `CONFIG.day` can move the clock those positions are evaluated at (start at a chosen date/time, optionally accelerated) without replacing the astronomy. - **Theme-tinted lighting**: each theme may pull the physical colours toward its own palette and set its own day/night exposure, without replacing the physics (`window.THEMES[...].lighting`). - **Shadows**: moving cloud shadows sampled from the same cloud field the sky renders, plus terrain self-shadowing over the DEM height field. - **Realistic night sky**: ~8700 stars from the Yale Bright Star Catalogue (points sized by magnitude, coloured by temperature), rotated at the sidereal rate for the site's latitude, a Milky Way band and a moon disc with a real lunar surface map: the terminator comes from the sun direction, so crescent, gibbous and full fall out of the geometry (sun and moon discs are drawn enlarged - `CONFIG.sun`/`CONFIG.moon` - while the lighting stays physical). - **Aircraft**: low-poly jets (own CC0 mesh, generated by `tools/plane_gen.py`) on curved routes between real airfields, with a destination rolled at every take-off, sun-lit silhouettes and contrails by day, strobing position lights by night. - **Night lights**: vehicle lights moving along the real road network (Overpass) with correct driving side per country, and settlement lights from OSM place nodes (bigger towns get more and brighter dots). Both fade in light by light across twilight instead of switching as one block. - **Live weather** (Open-Meteo): current conditions plus a 4-day forecast widget; the weather code selects the cloud coverage and the colour mood. - **Fully cached, offline-capable**: basemap tiles, the elevation grid, Overpass road/place cells, the merged road chains and the decoded settlement list live permanently in IndexedDB; the star catalogue is inlined. Once warm, the scene renders fully offline (only weather is fetched live), and a 15-minute cycle transparently retries anything that previously failed. - **Pixel-art rendering option**: `CONFIG.renderScale` renders the 3D scene at a fraction of the display size and upscales it in exact integer blocks with `image-rendering: pixelated`, while the DOM UI stays crisp. - **Location-aware**: set `CONFIG.location.lat/lon` and everything (flight anchor, terrain tiles, sun/moon, weather, star rotation, traffic side) is derived from it. Without a location, browser geolocation is tried, falling back to the built-in default. - Six UI languages, CSS-swappable colour themes, configurable clock format, optional debug panel. ## Run with Docker (recommended) ```sh docker compose up --build ``` Then open . The bundled nginx config (`default.conf`) is more than a file server: - CORS proxies for the basemap styles (`/esri/streets/`, `/esri/imagery/`) and the elevation tiles (`/terrarium/`). - CORS proxies for the three Overpass mirrors (`/overpass/api/`, `/overpass/coffee/`, `/overpass/mail/`) with a browser-like request, long timeouts and a 30-day `proxy_cache` (`overpass-cache.conf`) that also serves stale entries while a mirror is down. Public Overpass instances refuse or mis-handle cross-origin POSTs, and they are flaky; the cache means a cell the browser already paid for is never lost. - `Cache-Control: no-store` for HTML and JS, so a changed `CONFIG` takes effect on reload. The proxies are a convenience, not a requirement: every data source is also reachable directly from the browser (ESRI, the AWS elevation bucket and the Overpass mirrors all answer cross-origin requests), and the page probes for `/terrarium/` and `/esri/...` at start-up and switches to the proxy only when this same-origin proxy actually exists. Running the files from any static server therefore works as well - just without the nginx-side Overpass cache. ## Single-file build `build.py` bundles everything into one self-contained HTML file: all scripts, the star catalogue and every theme stylesheet are inlined, and theme switching keeps working. ```sh python3 build.py # -> background-standalone.html python3 build.py out.html # -> custom output path python3 build.py --check # build to a temp file and verify, write nothing ``` `--check` fails if anything is left that would need a sibling file (an external `