tower / commit
docs(tools): wait for the view before dragging it, and re-photograph the tour
README.md | 3 +- docs/screenshots/desktop-exterior-true.png | Bin 480301 -> 480678 bytes docs/screenshots/desktop-exterior.png | Bin 277525 -> 277782 bytes docs/screenshots/desktop-interior-night.png | Bin 237262 -> 237248 bytes docs/screenshots/desktop-interior-overhead.png | Bin 448992 -> 448986 bytes docs/screenshots/desktop-interior.png | Bin 452858 -> 452859 bytes docs/screenshots/mobile-exterior.png | Bin 70244 -> 70045 bytes docs/screenshots/mobile-interior.png | Bin 145358 -> 145370 bytes docs/screenshots/mobile-panel.png | Bin 72871 -> 72872 bytes docs/screenshots/overview.png | Bin 856785 -> 856749 bytes tools/screenshots.mjs | 71 ++++++++++++++++++++++--- 11 files changed, 65 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 18c7d81..56e7f34 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,8 @@ in the picture instead of hiding behind a passing unit test. |---|---| | [map](docs/screenshots/desktop-map.png) | the unrolled inner surface, with a place selected | | [map-sightline](docs/screenshots/desktop-map-sightline.png) | shift-click two points to measure a sightline through the air | -| [exterior](docs/screenshots/desktop-exterior.png) | hull, checkered end caps and the collector, terrain wrapped on as an x-ray | +| [exterior](docs/screenshots/desktop-exterior.png) | x-ray hull — the inner surface projected out, with the caps and the collector | +| [exterior-true](docs/screenshots/desktop-exterior-true.png) | true hull — bare skin, and the land visible through the far cap window | | [interior](docs/screenshots/desktop-interior.png) | standing at The Narrows, the ground curving up on both sides | | [interior-overhead](docs/screenshots/desktop-interior-overhead.png) | looking up: the far side 100 km overhead is clearer than ground 100 km away | | [reader](docs/screenshots/desktop-reader.png) | `?reader=1` — terrain, places, a detail card and the probe, no editing | diff --git a/docs/screenshots/desktop-exterior-true.png b/docs/screenshots/desktop-exterior-true.png index 1ac9f25..d666a43 100644 Binary files a/docs/screenshots/desktop-exterior-true.png and b/docs/screenshots/desktop-exterior-true.png differ diff --git a/docs/screenshots/desktop-exterior.png b/docs/screenshots/desktop-exterior.png index df28393..4d88325 100644 Binary files a/docs/screenshots/desktop-exterior.png and b/docs/screenshots/desktop-exterior.png differ diff --git a/docs/screenshots/desktop-interior-night.png b/docs/screenshots/desktop-interior-night.png index 66e9524..5d381a6 100644 Binary files a/docs/screenshots/desktop-interior-night.png and b/docs/screenshots/desktop-interior-night.png differ diff --git a/docs/screenshots/desktop-interior-overhead.png b/docs/screenshots/desktop-interior-overhead.png index 16924d7..d7e5a64 100644 Binary files a/docs/screenshots/desktop-interior-overhead.png and b/docs/screenshots/desktop-interior-overhead.png differ diff --git a/docs/screenshots/desktop-interior.png b/docs/screenshots/desktop-interior.png index 65fd822..ac6a76f 100644 Binary files a/docs/screenshots/desktop-interior.png and b/docs/screenshots/desktop-interior.png differ diff --git a/docs/screenshots/mobile-exterior.png b/docs/screenshots/mobile-exterior.png index f88fd92..93b9dc3 100644 Binary files a/docs/screenshots/mobile-exterior.png and b/docs/screenshots/mobile-exterior.png differ diff --git a/docs/screenshots/mobile-interior.png b/docs/screenshots/mobile-interior.png index 72eaf1b..8420958 100644 Binary files a/docs/screenshots/mobile-interior.png and b/docs/screenshots/mobile-interior.png differ diff --git a/docs/screenshots/mobile-panel.png b/docs/screenshots/mobile-panel.png index b935c1a..db4169c 100644 Binary files a/docs/screenshots/mobile-panel.png and b/docs/screenshots/mobile-panel.png differ diff --git a/docs/screenshots/overview.png b/docs/screenshots/overview.png index 1be84ad..516a14d 100644 Binary files a/docs/screenshots/overview.png and b/docs/screenshots/overview.png differ diff --git a/tools/screenshots.mjs b/tools/screenshots.mjs index 27c8ded..826f318 100644 --- a/tools/screenshots.mjs +++ b/tools/screenshots.mjs @@ -95,12 +95,29 @@ async function drag(page, [fx, fy], [tx, ty]) { await page.mouse.up() } -/** Open one of the three views by clicking its button, as a reader would. */ +/** + * Open one of the three views by clicking its button, as a reader would. + * + * Waits for the view to exist rather than for a guess at how long it takes. Three + * is a deferred import, so both 3D views appear some hundreds of milliseconds + * after the click — and a drag begun before the renderer has attached its pointer + * handlers is silently half-swallowed. That is not hypothetical: it is how + * interior-overhead came out pitched +13° when its drag is sized for +45°, and it + * had been doing so quietly for several runs behind a 2.5 s timeout that was + * usually but not always long enough. + * + * Both readouts are rendered only once their view is live, so a non-empty one is + * the signal — no app change needed to expose it. + */ async function openView(page, view) { await page.click(`#views button[data-view="${view}"]`) - // Three.js is a deferred import, so the first exterior or interior open is a - // network fetch and a shader compile before there is anything to photograph. - await page.waitForTimeout(view === 'map' ? 400 : 2500) + if (view !== 'map') { + await page.waitForFunction( + (sel) => (document.querySelector(sel)?.textContent ?? '').length > 0, + view === 'exterior' ? '#spin' : '#standing', + { timeout: 30_000 }) + } + await page.waitForTimeout(view === 'map' ? 400 : 700) await settle(page) } @@ -177,13 +194,14 @@ const SHOTS = [ }, { id: 'exterior', - caption: 'Exterior — hull, checkered end caps and the collector, terrain wrapped on as an x-ray', + caption: 'Exterior, x-ray hull — the inner surface projected out, with the caps and the collector', on: ['desktop', 'mobile'], run: async (page) => { await openView(page, 'exterior') // Spin off: a turning Tower photographs differently every run, and the value // of these images is that a difference means something. await withPanel(page, () => page.uncheck('#f-spin')) + await withPanel(page, () => page.selectOption('#f-ext-view', 'xray')) const s = await stage(page) await drag(page, [s.x + s.w * 0.5, s.y + s.h * 0.5], [s.x + s.w * 0.5 - 150, s.y + s.h * 0.5 + 70]) // The default view sits about 1,200 km out, where Tower is a sliver. Close in @@ -197,6 +215,26 @@ const SHOTS = [ await settle(page, 3000) }, }, + { + id: 'exterior-true', + caption: 'Exterior, true hull — bare skin, and the land visible in through the far cap window', + on: ['desktop'], + run: async (page) => { + await openView(page, 'exterior') + await withPanel(page, () => page.uncheck('#f-spin')) + await withPanel(page, () => page.selectOption('#f-ext-view', 'true')) + // Swing round to the far cap: the window is the whole point of this mode and + // it is at one specific end of a 540 km object. + await pick(page, 'The Far Cap') + const s = await stage(page) + await page.mouse.move(s.x + s.w * 0.5, s.y + s.h * 0.5) + for (let i = 0; i < 3; i++) { + await page.mouse.wheel(0, -400) + await page.waitForTimeout(120) + } + await settle(page, 3000) + }, + }, { id: 'interior', caption: 'Interior — standing at The Narrows, the ground curving up on both sides', @@ -217,10 +255,14 @@ const SHOTS = [ const s = await stage(page) /** * Dragging down pitches the view up. The interior turns at 0.0032 rad per - * pixel at the default 60° field, so ~245 px is 45° — high enough to have the - * far side of the world in frame, low enough to keep the ground in it too. + * pixel at the default 60° field, so 164 px is 30°. + * + * It was 245 px / 45° until the far cap became a window. At 45° the frame is + * almost all haze — which is honest, and a poor picture of the claim in the + * caption. 30° keeps the ground's edge curving up on one side and the cap on + * the other, which is what the shot is actually for. */ - await drag(page, [s.x + s.w * 0.5, s.y + s.h * 0.32], [s.x + s.w * 0.5, s.y + s.h * 0.32 + 245]) + await drag(page, [s.x + s.w * 0.5, s.y + s.h * 0.32], [s.x + s.w * 0.5, s.y + s.h * 0.32 + 164]) await page.check('#f-rain') await settle(page, 1600) }, @@ -237,6 +279,19 @@ const SHOTS = [ await settle(page) }, }, + { + id: 'interior-night', + caption: 'Interior — the far cap window at night: stars, and the beam banked to a thousandth', + on: ['desktop'], + run: async (page) => { + await openView(page, 'interior') + // The Capital is 270 km from the far cap, which is far enough to see the + // whole 100 km window and near enough that some of the sky survives the air. + await pick(page, 'The Capital') + await withPanel(page, () => page.selectOption('#f-light', 'night')) + await settle(page, 1600) + }, + }, { id: 'reader', caption: 'Reader mode (?reader=1) — terrain, places, a detail card and the probe, no editing',