feat(stammbaum): add clampZoom with resolved 0.25–3.0 zoom bounds (#692)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
26
frontend/src/lib/person/genealogy/panZoom.test.ts
Normal file
26
frontend/src/lib/person/genealogy/panZoom.test.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { clampZoom, MIN_ZOOM, MAX_ZOOM } from './panZoom';
|
||||||
|
|
||||||
|
describe('clampZoom', () => {
|
||||||
|
it('returns the value unchanged when within range', () => {
|
||||||
|
expect(clampZoom(1)).toBe(1);
|
||||||
|
expect(clampZoom(0.5)).toBe(0.5);
|
||||||
|
expect(clampZoom(2.75)).toBe(2.75);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clamps below MIN_ZOOM up to MIN_ZOOM', () => {
|
||||||
|
expect(clampZoom(0.1)).toBe(MIN_ZOOM);
|
||||||
|
expect(clampZoom(0)).toBe(MIN_ZOOM);
|
||||||
|
expect(clampZoom(-5)).toBe(MIN_ZOOM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clamps above MAX_ZOOM down to MAX_ZOOM', () => {
|
||||||
|
expect(clampZoom(5)).toBe(MAX_ZOOM);
|
||||||
|
expect(clampZoom(3.0001)).toBe(MAX_ZOOM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exposes the resolved zoom bounds', () => {
|
||||||
|
expect(MIN_ZOOM).toBe(0.25);
|
||||||
|
expect(MAX_ZOOM).toBe(3.0);
|
||||||
|
});
|
||||||
|
});
|
||||||
19
frontend/src/lib/person/genealogy/panZoom.ts
Normal file
19
frontend/src/lib/person/genealogy/panZoom.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Pan/zoom geometry for the Stammbaum canvas (#692).
|
||||||
|
*
|
||||||
|
* The Stammbaum renders zoom by deriving the SVG `viewBox` rather than applying
|
||||||
|
* a CSS transform (see `StammbaumTree.svelte`). This module is the single source
|
||||||
|
* of truth for the zoom bounds, the view-state shape, and every pure geometry
|
||||||
|
* helper used by the gesture action, the URL serialiser, and the page. Keeping
|
||||||
|
* the math here (and free of DOM access) makes it unit-testable in the node
|
||||||
|
* project. See ADR-026 for why this is custom rather than a third-party library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Resolved zoom bounds (OQ-001). */
|
||||||
|
export const MIN_ZOOM = 0.25;
|
||||||
|
export const MAX_ZOOM = 3.0;
|
||||||
|
|
||||||
|
/** Clamp a zoom factor into the supported range. */
|
||||||
|
export function clampZoom(z: number): number {
|
||||||
|
return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, z));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user