Split settings into tabs; exposure and focus on the home screen
Some checks failed
CI / build-and-deploy (push) Has been cancelled
Some checks failed
CI / build-and-deploy (push) Has been cancelled
Home screen gains shutter, aperture and ISO as dropdowns plus a focus stepper (three nudge sizes each way, and AF) where the body drives focus over PTP. Those three drop out of the read-only strip rather than being shown twice. Everything is built from what the camera actually reports, so a body without one of these controls doesn't get it rather than showing something that silently fails. The 450D marks shutter and aperture readonly unless the mode dial is somewhere they apply, so the dropdowns disable themselves and say why. Focus uses the EOS manualfocusdrive steps and autofocusdrive, and warns when live view is off, which Canon bodies generally require for focus commands. The settings drawer is now tabbed: app settings stay on the first tab, and each config section the camera reports gets its own. Empty sections are dropped, and a selected section that disappears falls back to the first tab. Tabs wrap rather than scroll - a scrolled-off tab is an undiscoverable one. Reverts the automatic camera search added in the previous commit, restoring the Select camera button. Auto-connect could park with no way to reach the device chooser: WebUSB permissions are per-origin, so a grant on localhost doesn't carry to the deployed copy, and a camera that's asleep or held by another app never arrives. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QK7PKpRVoy69Fpa32R8abb
This commit is contained in:
14
README.md
14
README.md
@@ -58,7 +58,9 @@ npm install
|
||||
npx serve . # serve.json sets the COOP/COEP headers the WASM module needs
|
||||
```
|
||||
|
||||
Open the printed URL in Chrome and plug the camera in. It connects on its own — there's no connect button. The one exception is the very first visit, which shows a "Choose camera" prompt: Chrome will not open its WebUSB device chooser without a click. After that the permission is remembered, and `navigator.usb.getDevices()` finds the camera with no interaction, so later visits go straight in. If the camera is off or asleep the page sits on "Looking for your camera…" and keeps retrying, connecting the moment it wakes up.
|
||||
Open the printed URL in Chrome, plug the camera in over USB, switch it on and pick it from the device picker. It tries once on load to reattach to a camera the browser already knows about, and otherwise shows a "Select camera" button.
|
||||
|
||||
Note that WebUSB permissions are per-origin, so the copy on `localhost` and the deployed copy each need granting separately.
|
||||
|
||||
It's also an installable PWA: install it from Chrome's address bar to get a standalone window, and it works with no network at all — the app shell and the pinned unpkg dependencies (including the ~2 MB WASM) are precached by a service worker. That matters here because the camera is on a USB cable, so the app is perfectly useful in a field with no signal.
|
||||
|
||||
@@ -69,7 +71,8 @@ It's also an installable PWA: install it from Chrome's address bar to get a stan
|
||||
- Live countdown to the next frame, progress, estimated finish time, and a log of the last few events
|
||||
- A 🔊 toggle that speaks the countdown into each frame ("five, four, three, two, one") along with start and finish, for when you're in front of the camera rather than at the laptop
|
||||
- A ⛶ button on the preview for a fullscreen live view, with the countdown carried over as an overlay so you don't lose it
|
||||
- A read-only strip showing shutter / aperture / ISO / format / battery / shots remaining, so you can sanity-check exposure against the interval without opening anything
|
||||
- Shutter, aperture and ISO as dropdowns, and a focus stepper (three nudge sizes each way, plus AF) where the body drives focus over PTP
|
||||
- A read-only strip for the rest — mode, format, battery, shots remaining — so you can sanity-check the run without opening anything
|
||||
- Pre-flight warnings when the interval is too tight for the current exposure and transfer time, when you're shooting RAW on a short interval, or when no output folder is set
|
||||
|
||||
**Settings drawer** (⚙, top right) — everything else, including the full gPhoto2 config tree, so the home screen stays uncluttered:
|
||||
@@ -97,6 +100,13 @@ Live at <https://dslr-intervalometer.bournemouthtech.workers.dev>.
|
||||
|
||||
The one thing a static host has to get right here: the WASM module is built with pthreads and allocates a **shared** `WebAssembly.Memory`, so the page must be [cross-origin isolated](https://web.dev/coop-coep/) or it fails to start outright. `_headers` sets the same COOP/COEP pair `serve.json` uses locally. If you host this anywhere else, set those two headers or nothing will work. Verify with `crossOriginIsolated === true` in the console.
|
||||
|
||||
Notes on the exposure and focus controls:
|
||||
|
||||
- They're built from whatever the camera actually reports, so a body that doesn't expose one of them simply doesn't get that control rather than showing something that silently fails.
|
||||
- The 450D marks shutter and aperture read-only unless the mode dial is somewhere they apply — both are fixed in the green square, shutter in Av, aperture in Tv. When that happens the dropdowns disable themselves and say so rather than appearing to work.
|
||||
- Focus uses the EOS `manualfocusdrive` steps ("Near 1".."Far 3") and `autofocusdrive` for AF. Canon bodies generally only accept focus commands with live view running, so the panel warns if you've turned live view off.
|
||||
- Every change is a USB round-trip taking the best part of a second, and it shares the link with captures — changing settings mid-sequence works but can delay a frame.
|
||||
|
||||
Notes on the timing and its limits:
|
||||
|
||||
- Frames are scheduled on an absolute grid (`start + n × interval`), so transfer time doesn't accumulate as drift over a long run. If a capture overruns its slot the next frame fires as soon as the camera is free and the overrun is logged, rather than a frame being dropped.
|
||||
|
||||
Reference in New Issue
Block a user