feat(stammbaum): recentre-on-node with legible auto-zoom (#692)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-29 16:29:55 +02:00
parent 5d752fcc0f
commit 197b668f20
2 changed files with 48 additions and 0 deletions

View File

@@ -14,6 +14,9 @@ export const MIN_ZOOM = 0.25;
export const MAX_ZOOM = 3.0;
export const DEFAULT_ZOOM = 1;
/** Minimum zoom a recentre will snap up to so the focal node's text is legible (OQ-005). */
export const LEGIBLE_ZOOM = 1;
/**
* The canvas view state. `x`/`y` are pan offsets applied to the viewBox centre
* (SVG user units); `z` is the zoom factor. The default `{0, 0, 1}` frames the
@@ -106,3 +109,23 @@ export function zoomAtPoint(
z
};
}
/**
* Pan so a node sits at the viewBox centre (US-PAN-005). Because the viewBox
* centre is `baseCentre + pan` independent of zoom, centring is a pure pan:
* `pan = nodeCentre - baseCentre`. When `autoZoom` is set, a zoomed-out view is
* snapped up to {@link LEGIBLE_ZOOM} so the focal node's text is readable
* (OQ-005); an already-legible zoom is preserved.
*/
export function recentreOn(
nodeCentre: { x: number; y: number },
baseCentre: { x: number; y: number },
state: PanZoomState,
autoZoom: boolean
): PanZoomState {
return {
x: nodeCentre.x - baseCentre.x,
y: nodeCentre.y - baseCentre.y,
z: autoZoom ? clampZoom(Math.max(state.z, LEGIBLE_ZOOM)) : state.z
};
}