Zoom: compose the box as a real 2x layer above the background (Unit: zoom layer + magnification proof)

Right-click now creates a transient ZoomSceneElement at z-index 1 whose pixels are a
genuine 2x magnified sample of the backdrop (live capture under art), composited into
stream/recording like any layer while the output crop stays the tier. All shapes are
centered on the click and clamped to frame; healed on load/scene-create, never persisted,
hidden from the layers list + element template (IsZoomLayer). BuildCompositorOptions is
now internal = always tier crop (test seam). ZoomFrameBuilder is a pure static sampler
(box/2 window centered on the box center, single-slot cache) proven by a banded-backdrop
test; LayerReorderPersistenceTests drag resolves rows by item since the collapsed zoom
row shifts container indices. Also books TASK 51 (webcam background Remove + Blur) and
syncs memory docs (HANDOFF, MyMistakes, indexes). Full suite: 405 passed, 0 warnings.
This commit is contained in:
2026-10-07 23:39:54 -07:00
parent 966e718f1e
commit 4b3d82ff0f
17 changed files with 734 additions and 210 deletions
+28
View File
@@ -0,0 +1,28 @@
using System.Windows.Media;
namespace ytLive.Models;
/// <summary>
/// The transient zoom layer: a real scene element parked at z-index 1 (above the
/// background, below every other layer) whose pixels are the 2x-magnified backdrop
/// centred on the zoom box. The app paints it into the stream/recording exactly like
/// any other layer. While inactive it is a 0x0 invisible placeholder that is never
/// persisted (LayoutStore hand-rolls only Source/WebcamSceneConfig rows) — the VM
/// re-inserts it on load and on scene creation, mirroring how backgrounds heal.
/// </summary>
public sealed class ZoomSceneElement : SceneElement
{
/// <summary>True only while a zoom box is live; flips Kind so the layer leaves
/// the baked static base and composites per-frame.</summary>
public bool IsZoomActive { get; set; }
public override ElementKind Kind => IsZoomActive ? ElementKind.Dynamic : ElementKind.Static;
public override bool IsZoomLayer => true;
public override bool IsDraggable => false;
/// <summary>Never rendered by the element template — the preview magnifier
/// (ZoomBox) and the output resolver own its pixels.</summary>
public override ImageSource? DisplaySource => null;
}