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:
@@ -553,13 +553,15 @@ public partial class PreviewPane : UserControl
|
||||
if (DataContext is not MainViewModel vm) return;
|
||||
if (vm.IsZoomActive && ZoomVisualBrush != null)
|
||||
{
|
||||
// The preview mirrors the output zoom layer: sample the backdrop layer
|
||||
// (the live capture + art, exactly what the compositor magnifies) at the
|
||||
// box/2 interior centered on the box center → 2x on the screen.
|
||||
ZoomVisualBrush.Visual = BackdropLayer;
|
||||
// The preview mirrors the output zoom layer: sample the WHOLE composed
|
||||
// preview (CanvasGrid = backdrop + every element layer — the same all-layer
|
||||
// source the output compositor magnifies) at the FIXED capture window (the
|
||||
// box/2 region centred on the click) → 2x via Stretch=Fill. Moving the box
|
||||
// only moves the ZoomBox element; the Viewbox stays glued to the capture.
|
||||
ZoomVisualBrush.Visual = CanvasGrid;
|
||||
ZoomVisualBrush.Viewbox = new Rect(
|
||||
vm.ZoomState.X + vm.ZoomState.Width / 4,
|
||||
vm.ZoomState.Y + vm.ZoomState.Height / 4,
|
||||
vm.ZoomState.CaptureX,
|
||||
vm.ZoomState.CaptureY,
|
||||
vm.ZoomState.Width / 2,
|
||||
vm.ZoomState.Height / 2);
|
||||
ZoomVisualBrush.ViewboxUnits = BrushMappingMode.Absolute;
|
||||
@@ -576,7 +578,7 @@ public partial class PreviewPane : UserControl
|
||||
ZoomBox.Clip = null;
|
||||
}
|
||||
}
|
||||
else if (!vm.IsZoomActive && ZoomVisualBrush != null && ReferenceEquals(ZoomVisualBrush.Visual, BackdropLayer))
|
||||
else if (!vm.IsZoomActive && ZoomVisualBrush != null && ReferenceEquals(ZoomVisualBrush.Visual, CanvasGrid))
|
||||
{
|
||||
ZoomVisualBrush.Visual = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user