The review items offered on #608, applied on top of the contributor's
zoom:
- `object-fit: scale-down` instead of `contain`, so a small image keeps
its own size instead of being stretched to fill the preview. The pan
clamp now uses the size the image is actually drawn at (natural size
fitted with scale-down) rather than the image box, which let a small
or letterboxed image be panned entirely out of view.
- Wheel zoom is proportional to deltaY (d3-zoom's scale: about 15% per
100px notch, lines and ctrl+wheel trackpad pinches scaled up), capped
at sqrt(2) per event, and a wheel event with no vertical delta zooms
nothing. A trackpad scroll no longer jumps to 600%.
- The zoom controls show only once the image has loaded; on an error
they are hidden and the gesture listeners are dropped with the image.
Both handlers now check the request sequence like the text branch, so
a late load or error from a replaced preview no longer resets the
current preview's zoom or paints its error over the current image.
- test/path-picker-image-zoom.test.ts drives the real listeners in
jsdom (focal point under the cursor and the pinch centre, pan clamp,
wheel scaling, error, close and stale events) in place of the
source-string checks in test/path-picker-ui.test.ts. 7 of its 10
tests fail against the contributor's commit alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>