fix(zoom): stop re-baseline scale oscillation
Device log showed the applied scale oscillating ~1.4x every frame while the raw pinch was smooth (cur 1.116->0.797->1.074, raw ~0.46). Root cause: on a pointer-count re-baseline (Windows touch flickers 2<->1<->2 mid-pinch) the code set _scaleStart = matrix.getMaxScaleOnAxis() — a read-back captured at a glitchy instant — so the absolute map K = scaleStart/rawScaleAtBaseline jumped frame to frame. Fix: anchor the re-baseline to the CLEAN tracked _lastAppliedScale instead of the live matrix read-back, so the displayed scale is continuous across the re-baseline regardless of any matrix transient. The math is already covered by the pinch_scale_solver "same-instant re-baseline" test; this just feeds it the right value. flutter analyze: 0. pinch_scale_solver + pen_zoom: pass.
This commit is contained in:
@@ -194,13 +194,20 @@ class _PenInteractiveViewerState extends State<PenInteractiveViewer>
|
||||
// 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;
|
||||
|
||||
Reference in New Issue
Block a user