feat(stammbaum): drive viewBox from PanZoomState (pan + zoom) (#692)
Replace the scalar zoom prop with a {x,y,z} PanZoomState. The viewBox centre
is offset by the pan and width/height scaled by zoom; the default {0,0,1}
frames the whole tree (fit-to-screen). Page header buttons now step view.z
through clampZoom over the resolved 0.25–3.0 range.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,12 @@ import { m } from '$lib/paraglide/messages.js';
|
||||
import { page } from '$app/state';
|
||||
import StammbaumTree from '$lib/person/genealogy/StammbaumTree.svelte';
|
||||
import StammbaumSidePanel from '$lib/person/genealogy/StammbaumSidePanel.svelte';
|
||||
import {
|
||||
type PanZoomState,
|
||||
DEFAULT_VIEW,
|
||||
clampZoom,
|
||||
ZOOM_STEP_KB
|
||||
} from '$lib/person/genealogy/panZoom';
|
||||
import type { components } from '$lib/generated/api';
|
||||
|
||||
type PersonNodeDTO = components['schemas']['PersonNodeDTO'];
|
||||
@@ -23,12 +29,12 @@ let selectedId = $state<string | null>(
|
||||
|
||||
const selectedNode = $derived(data.nodes.find((n) => n.id === selectedId) ?? null);
|
||||
|
||||
let zoom = $state(1);
|
||||
let view = $state<PanZoomState>(DEFAULT_VIEW);
|
||||
function zoomIn() {
|
||||
zoom = Math.min(2, zoom + 0.1);
|
||||
view = { ...view, z: clampZoom(view.z + ZOOM_STEP_KB) };
|
||||
}
|
||||
function zoomOut() {
|
||||
zoom = Math.max(0.4, zoom - 0.1);
|
||||
view = { ...view, z: clampZoom(view.z - ZOOM_STEP_KB) };
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -97,7 +103,7 @@ function zoomOut() {
|
||||
nodes={data.nodes}
|
||||
edges={data.edges}
|
||||
selectedId={selectedId}
|
||||
zoom={zoom}
|
||||
panZoom={view}
|
||||
onSelect={(id) => (selectedId = id)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user