diff --git a/lib/editor/canvas/pen_interactive_viewer.dart b/lib/editor/canvas/pen_interactive_viewer.dart index 52d7c40..4c60988 100644 --- a/lib/editor/canvas/pen_interactive_viewer.dart +++ b/lib/editor/canvas/pen_interactive_viewer.dart @@ -194,13 +194,20 @@ class _PenInteractiveViewerState extends State // The transitional frame itself is skipped. if (details.pointerCount != _lastPointerCount) { _lastPointerCount = details.pointerCount; - _scaleStart = _transformer.value.getMaxScaleOnAxis(); + // Anchor the new baseline to the CLEAN tracked scale (_lastAppliedScale), + // NOT a fresh matrix read-back. Windows touch flickers the pointer count + // (2↔1↔2) mid-pinch, firing this re-baseline spuriously; reading + // getMaxScaleOnAxis() at that glitchy instant popped _scaleStart to a + // noisy value, so the absolute map K = scaleStart / rawScaleAtBaseline + // oscillated frame-to-frame (the reported "zoom jump"). Using + // _lastAppliedScale makes the displayed scale CONTINUOUS across the + // re-baseline: target == _lastAppliedScale at this instant, regardless of + // any transient in the live matrix. + _scaleStart = _lastAppliedScale; _referenceFocalPoint = _transformer.toScene(details.localFocalPoint); _lastRawScale = details.scale; - _lastAppliedScale = _scaleStart!; - // Re-anchor the absolute mapping: from here, cumulative scale is measured - // relative to THIS frame's details.scale (so the next good frame starts - // from _scaleStart, not _scaleStart * a stale cumulative value). + // Re-anchor the cumulative scale to THIS frame's details.scale so the next + // good frame resumes from _scaleStart (not _scaleStart × a stale ratio). _rawScaleAtBaseline = details.scale; InputDiagnostics.instance.recordRebaseline(); return;