diff --git a/examples/react/src/examples/ControlledViewport/index.tsx b/examples/react/src/examples/ControlledViewport/index.tsx index ebf4d029..dcd98ce9 100644 --- a/examples/react/src/examples/ControlledViewport/index.tsx +++ b/examples/react/src/examples/ControlledViewport/index.tsx @@ -1,4 +1,4 @@ -import { MouseEvent, useCallback, useState } from 'react'; +import { MouseEvent, useCallback, useRef, useState } from 'react'; import { ReactFlow, addEdge, @@ -55,10 +55,18 @@ const Flow = () => { const [nodes, setNodes, onNodesChange] = useNodesState(initNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initEdges); const [viewport, setViewport] = useState({ x: 0, y: 0, zoom: 1 }); + const [viewport2, setViewport2] = useState({ x: 100, y: 100, zoom: 1.5 }); + const [currentViewport, setCurrentViewport] = useState(0); const { fitView } = useReactFlow(); const onConnect = useCallback((params: Connection | Edge) => setEdges((eds) => addEdge(params, eds)), [setEdges]); + const setter = currentViewport === 0 ? setViewport : setViewport2; + + const toggleViewport = () => { + setCurrentViewport(currentViewport === 0 ? 1 : 0); + }; + return ( { onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} - viewport={viewport} - onViewportChange={setViewport} + viewport={currentViewport === 0 ? viewport : viewport2} + onViewportChange={setter} > - + + diff --git a/packages/react/src/container/ZoomPane/index.tsx b/packages/react/src/container/ZoomPane/index.tsx index 3d4003e0..35fbb248 100644 --- a/packages/react/src/container/ZoomPane/index.tsx +++ b/packages/react/src/container/ZoomPane/index.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { useEffect, useRef } from 'react'; +import { useCallback, useEffect, useRef } from 'react'; import { shallow } from 'zustand/shallow'; import { XYPanZoom, PanOnScrollMode, type Transform, type PanZoomInstance } from '@xyflow/system'; @@ -57,6 +57,17 @@ export function ZoomPane({ useResizeHandler(zoomPane); + const onTransformChange = useCallback( + (transform: Transform) => { + onViewportChange?.({ x: transform[0], y: transform[1], zoom: transform[2] }); + + if (!isControlledViewport) { + store.setState({ transform }); + } + }, + [onViewportChange, isControlledViewport] + ); + useEffect(() => { if (zoomPane.current) { panZoom.current = XYPanZoom({ @@ -66,13 +77,6 @@ export function ZoomPane({ translateExtent, viewport: defaultViewport, paneClickDistance, - onTransformChange: (transform: Transform) => { - onViewportChange?.({ x: transform[0], y: transform[1], zoom: transform[2] }); - - if (!isControlledViewport) { - store.setState({ transform }); - } - }, onDraggingChange: (paneDragging: boolean) => store.setState({ paneDragging }), onPanZoomStart: (event, vp) => { const { onViewportChangeStart, onMoveStart } = store.getState(); @@ -121,6 +125,7 @@ export function ZoomPane({ userSelectionActive, noWheelClassName, lib, + onTransformChange, }); }, [ onPaneContextMenu, @@ -137,6 +142,7 @@ export function ZoomPane({ userSelectionActive, noWheelClassName, lib, + onTransformChange, ]); return ( diff --git a/packages/svelte/src/lib/actions/zoom/index.ts b/packages/svelte/src/lib/actions/zoom/index.ts index a0c83c31..85070d68 100644 --- a/packages/svelte/src/lib/actions/zoom/index.ts +++ b/packages/svelte/src/lib/actions/zoom/index.ts @@ -5,6 +5,7 @@ import { type CoordinateExtent, type OnPanZoom, type PanZoomInstance, + type Transform, type Viewport } from '@xyflow/system'; @@ -36,6 +37,7 @@ type ZoomParams = { userSelectionActive: boolean; lib: string; paneClickDistance: number; + onTransformChange: (transform: Transform) => void; }; export default function zoom(domNode: Element, params: ZoomParams) { @@ -57,8 +59,6 @@ export default function zoom(domNode: Element, params: ZoomParams) { translateExtent, viewport: initialViewport, paneClickDistance, - onTransformChange: (transform) => - viewport.set({ x: transform[0], y: transform[1], zoom: transform[2] }), onDraggingChange: dragging.set }); const currentViewport = panZoomInstance.getViewport(); diff --git a/packages/svelte/src/lib/container/Zoom/Zoom.svelte b/packages/svelte/src/lib/container/Zoom/Zoom.svelte index adb4463d..4148d278 100644 --- a/packages/svelte/src/lib/container/Zoom/Zoom.svelte +++ b/packages/svelte/src/lib/container/Zoom/Zoom.svelte @@ -1,10 +1,10 @@