Zoom: anchor the capture, magnify the full composite, draw on top (Unit: zoom rework per creator correction)
Creator corrected the "loupe" zoom on 2026-10-08: the click anchors a fixed
capture region (box/2 centred on the click) and the box is a live 2x view of
that region — dragging the box never changes its content; it magnifies the
fully-composited frame (every layer, incl. webcam) and draws LAST (n+1).
Rectangle shape is 4:3 ("more of a 640x480 aspect").
- MainViewModel.Zoom.cs rewritten: ActivateZoom anchors CaptureX/CaptureY
(independently clamped); UpdateZoomMove relocates the box only; the per-frame
BuildZoomFrame/ZoomFrameBuilder path is gone.
- SceneCompositor: skips the active ZoomSceneElement in every layer loop and
BlitZooms it last via the new pure ZoomMagnifier (2x bilinear, temp snapshot
via ArrayPool, round clip).
- Preview: ZoomBox hoisted above CanvasGrid as a sibling; its brush samples the
whole composed preview at the fixed capture (2x).
- Tests: ZoomMagnifierTests (box-over-blue shows green capture at 2x incl. an
extra red "layer" — the loupe/backdrop-only regressions both fail it) +
round-clip; ZoomBoxInteractionTests rewritten (anchored capture, move-doesn't-
change-capture, 4:3/9:16/square). 404 pass, 2 known environment flakes.
This commit is contained in:
@@ -1526,3 +1526,22 @@ A one-constant difference (`W/4` vs nothing) is invisible in a real scene but fa
|
||||
gradient test — which is exactly why the magnification proof exists: 4 vertical bands, a box whose
|
||||
1x region straddles two of them, assert ALL output pixels are the center-band color. If you change
|
||||
the preview window, change `ZoomFrameBuilder` in the same edit or the preview lies about the output.
|
||||
|
||||
## 2026-10-08 — The zoom box is NOT a loupe: anchored capture, all-layer content, drawn LAST
|
||||
|
||||
I shipped the whole first zoom layer (commit `4b3d82f`) with a "loupe" mental model — the box shows
|
||||
what's *under it* in the output — and the creator corrected it in one message: the click fixes a
|
||||
**capture region** and the box is a live, always-on 2x view of THAT region; moving the box changes
|
||||
NOTHING about its content; it magnifies the fully-composited frame (every layer, including webcam),
|
||||
and it must draw **on top of everything** (layer n+1), not slot at z-index 1. Three wrongs, all made
|
||||
"elegantly": a BoxFollowing frame builder, a Backdrop+first-layer-only sample, and a z=1 layering.
|
||||
|
||||
The corrected test that would have caught all three in one shot (`ZoomMagnifierTests`): a banded
|
||||
buffer (blue left / green right) with the box's left quarter OVER a blue region while the capture
|
||||
sits wholly in green — assert **no box pixel is blue**. A loupe-style sampler fails it, a backdrop-
|
||||
only sampler fails the "red webcam square appears magnified" assert, and `SceneCompositor` skips the
|
||||
active zoom in every layer loop so nothing else can cover it. Lessons: (1) ask the *triggering
|
||||
semantics* — anchored-capture vs follow-the-box — before building any "zoom" UI; (2) prove content
|
||||
captures ALL layers with an extra layer in the fixture and assert it appears; (3) "draw above
|
||||
everything" is a compositor ordering property (skip in the layer loops + blit last), not a z-index
|
||||
of the element among the others.
|
||||
|
||||
Reference in New Issue
Block a user