refactor(stammbaum): extract + unit-test pinch and inertia math (#692)
Move the pinch-zoom (pinchZoom) and inertia-step (stepInertia) geometry out of the panZoomGestures DOM glue into pure, unit-tested helpers in panZoom.ts, with named FRAME_MS/INERTIA_* constants. Addresses the QA blocker that the gesture module's core math was untested. No behaviour change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -130,6 +130,43 @@ export function zoomAtPoint(
|
||||
};
|
||||
}
|
||||
|
||||
/** Assumed milliseconds per animation frame, used to scale inertia velocity. */
|
||||
export const FRAME_MS = 16;
|
||||
/** Per-frame velocity decay for pan inertia (OQ-004). */
|
||||
export const INERTIA_DECAY = 0.92;
|
||||
/** Inertia stops once the velocity (svg units per ms) drops below this. */
|
||||
export const INERTIA_MIN_SPEED = 0.02;
|
||||
|
||||
/**
|
||||
* Pinch zoom around the gesture centroid (US-PAN-002/003). The new zoom is the
|
||||
* start zoom scaled by the finger-distance ratio (clamped); the anchor offset
|
||||
* keeps the centroid fixed via {@link zoomAtPoint}.
|
||||
*/
|
||||
export function pinchZoom(
|
||||
state: PanZoomState,
|
||||
startZoom: number,
|
||||
startDist: number,
|
||||
currentDist: number,
|
||||
anchorX: number,
|
||||
anchorY: number
|
||||
): PanZoomState {
|
||||
const ratio = startDist > 0 ? currentDist / startDist : 1;
|
||||
return zoomAtPoint(state, clampZoom(startZoom * ratio), anchorX, anchorY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance the pan by one inertia frame: continue the release velocity (svg units
|
||||
* per ms) in the drag direction, scaled by the frame duration. Zoom is untouched.
|
||||
*/
|
||||
export function stepInertia(
|
||||
state: PanZoomState,
|
||||
velX: number,
|
||||
velY: number,
|
||||
frameMs: number = FRAME_MS
|
||||
): PanZoomState {
|
||||
return { x: state.x - velX * frameMs, y: state.y - velY * frameMs, z: state.z };
|
||||
}
|
||||
|
||||
/** Linearly interpolate between two view states (drives fit/recentre tweening). */
|
||||
export function lerpView(from: PanZoomState, to: PanZoomState, t: number): PanZoomState {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user