Skip to content

Commit 6669fc6

Browse files
committed
Fix fit-to-view bounds calculation for center-origin nodes
1 parent 8b7c3fc commit 6669fc6

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

src/lib/components/FlowCanvas.svelte

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import { nodeRegistry } from '$lib/nodes';
3131
import { NODE_TYPES } from '$lib/constants/nodeTypes';
3232
import { SNAP_GRID, BACKGROUND_GAP } from '$lib/constants/grid';
33+
import { calculateNodeDimensions } from '$lib/constants/dimensions';
3334
import type { NodeInstance, Connection, Annotation } from '$lib/nodes/types';
3435
import type { EventInstance } from '$lib/events/types';
3536
@@ -381,6 +382,20 @@
381382
// Interface blocks are not deletable
382383
const isInterface = graphNode.type === NODE_TYPES.INTERFACE;
383384
385+
// Calculate node dimensions for SvelteFlow bounds
386+
const typeDef = nodeRegistry.get(graphNode.type);
387+
const pinnedParamCount = typeDef && graphNode.pinnedParams
388+
? graphNode.pinnedParams.filter(name => typeDef.params.some(p => p.name === name)).length
389+
: 0;
390+
const rotation = (graphNode.params?.['_rotation'] as number) || 0;
391+
const { width, height } = calculateNodeDimensions(
392+
graphNode.name,
393+
graphNode.inputs.length,
394+
graphNode.outputs.length,
395+
pinnedParamCount,
396+
rotation
397+
);
398+
384399
// If node exists, update data but don't preserve selection here
385400
// Selection is managed by SvelteFlow, trigger subscriptions, and merge effect
386401
if (existingNode) {
@@ -389,6 +404,10 @@
389404
type: existingNode.type,
390405
position,
391406
data: graphNode,
407+
width,
408+
height,
409+
// Explicit center origin for correct bounds calculation
410+
origin: [0.5, 0.5] as [number, number],
392411
selectable: existingNode.selectable,
393412
draggable: existingNode.draggable,
394413
deletable: !isInterface
@@ -402,6 +421,10 @@
402421
type: 'pathview',
403422
position,
404423
data: graphNode,
424+
width,
425+
height,
426+
// Explicit center origin for correct bounds calculation
427+
origin: [0.5, 0.5] as [number, number],
405428
selectable: true,
406429
draggable: true,
407430
deletable: !isInterface

src/lib/components/FlowUpdater.svelte

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,19 @@
3030
return;
3131
}
3232
33-
// Calculate bounding box of all nodes
33+
// Calculate bounding box of all nodes, accounting for origin
3434
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
3535
for (const node of nodes) {
3636
const width = node.measured?.width ?? node.width ?? 160;
3737
const height = node.measured?.height ?? node.height ?? 60;
38-
minX = Math.min(minX, node.position.x);
39-
minY = Math.min(minY, node.position.y);
40-
maxX = Math.max(maxX, node.position.x + width);
41-
maxY = Math.max(maxY, node.position.y + height);
38+
// Account for node origin (default center [0.5, 0.5], annotations use [0, 0])
39+
const origin = (node.origin as [number, number]) ?? [0.5, 0.5];
40+
const left = node.position.x - width * origin[0];
41+
const top = node.position.y - height * origin[1];
42+
minX = Math.min(minX, left);
43+
minY = Math.min(minY, top);
44+
maxX = Math.max(maxX, left + width);
45+
maxY = Math.max(maxY, top + height);
4246
}
4347
4448
// Add some padding around the nodes themselves

src/lib/components/canvas/flowConverters.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ export function toFlowNode(node: NodeInstance, options: { deletable?: boolean }
3535
data: node,
3636
width,
3737
height,
38+
// Explicit center origin for correct bounds calculation
39+
origin: [0.5, 0.5] as [number, number],
3840
selectable: true,
3941
draggable: true,
4042
deletable: options.deletable ?? true
@@ -50,6 +52,8 @@ export function toEventNode(event: EventInstance): Node<EventInstance> {
5052
type: 'eventNode',
5153
position: { ...event.position },
5254
data: event,
55+
// Explicit center origin for correct bounds calculation
56+
origin: [0.5, 0.5] as [number, number],
5357
selectable: true,
5458
draggable: true,
5559
connectable: false,

0 commit comments

Comments
 (0)