From 23fdd2065833ff5ef5a38bfb7d48df526a7c74b6 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 1 Sep 2022 12:37:13 +0200 Subject: [PATCH] fix(nodeOrigin): use origin for calculating handle position --- packages/core/src/components/Nodes/utils.ts | 13 +++++++++---- .../core/src/components/StoreUpdater/index.tsx | 3 +++ packages/core/src/container/ReactFlow/index.tsx | 1 + packages/core/src/store/index.ts | 14 +++++++++++--- packages/core/src/store/initialState.ts | 1 + packages/core/src/types/general.ts | 2 ++ 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/packages/core/src/components/Nodes/utils.ts b/packages/core/src/components/Nodes/utils.ts index 5d019168..b3116139 100644 --- a/packages/core/src/components/Nodes/utils.ts +++ b/packages/core/src/components/Nodes/utils.ts @@ -1,13 +1,14 @@ import { MouseEvent } from 'react'; import { StoreApi } from 'zustand'; -import { HandleElement, Node, Position, ReactFlowState } from '../../types'; +import { HandleElement, Node, NodeOrigin, Position, ReactFlowState } from '../../types'; import { getDimensions } from '../../utils'; export const getHandleBounds = ( selector: string, nodeElement: HTMLDivElement, - zoom: number + zoom: number, + nodeOrigin: NodeOrigin ): HandleElement[] | null => { const handles = nodeElement.querySelectorAll(selector); @@ -17,6 +18,10 @@ export const getHandleBounds = ( const handlesArray = Array.from(handles) as HTMLDivElement[]; const nodeBounds = nodeElement.getBoundingClientRect(); + const nodeOffset = { + x: nodeBounds.width * nodeOrigin[0], + y: nodeBounds.height * nodeOrigin[1], + }; return handlesArray.map((handle): HandleElement => { const handleBounds = handle.getBoundingClientRect(); @@ -24,8 +29,8 @@ export const getHandleBounds = ( return { id: handle.getAttribute('data-handleid'), position: handle.getAttribute('data-handlepos') as unknown as Position, - x: (handleBounds.left - nodeBounds.left) / zoom, - y: (handleBounds.top - nodeBounds.top) / zoom, + x: (handleBounds.left - nodeBounds.left - nodeOffset.x) / zoom, + y: (handleBounds.top - nodeBounds.top - nodeOffset.y) / zoom, ...getDimensions(handle), }; }); diff --git a/packages/core/src/components/StoreUpdater/index.tsx b/packages/core/src/components/StoreUpdater/index.tsx index 36bc858b..533a34c7 100644 --- a/packages/core/src/components/StoreUpdater/index.tsx +++ b/packages/core/src/components/StoreUpdater/index.tsx @@ -41,6 +41,7 @@ type StoreUpdaterProps = Pick< | 'onSelectionDrag' | 'onSelectionDragStop' | 'noPanClassName' + | 'nodeOrigin' >; const selector = (s: ReactFlowState) => ({ @@ -110,6 +111,7 @@ const StoreUpdater = ({ onSelectionDragStart, onSelectionDragStop, noPanClassName, + nodeOrigin, }: StoreUpdaterProps) => { const { setNodes, @@ -157,6 +159,7 @@ const StoreUpdater = ({ useDirectStoreUpdater('onSelectionDragStart', onSelectionDragStart, store.setState); useDirectStoreUpdater('onSelectionDragStop', onSelectionDragStop, store.setState); useDirectStoreUpdater('noPanClassName', noPanClassName, store.setState); + useDirectStoreUpdater('nodeOrigin', nodeOrigin, store.setState); useStoreUpdater(nodes, setNodes); useStoreUpdater(edges, setEdges); diff --git a/packages/core/src/container/ReactFlow/index.tsx b/packages/core/src/container/ReactFlow/index.tsx index 0cadc2a7..0a00cb9f 100644 --- a/packages/core/src/container/ReactFlow/index.tsx +++ b/packages/core/src/container/ReactFlow/index.tsx @@ -262,6 +262,7 @@ const ReactFlow = forwardRef( onSelectionDragStart={onSelectionDragStart} onSelectionDragStop={onSelectionDragStop} noPanClassName={noPanClassName} + nodeOrigin={nodeOrigin} /> {onSelectionChange && } {children} diff --git a/packages/core/src/store/index.ts b/packages/core/src/store/index.ts index ed83e72b..37d6ad2b 100644 --- a/packages/core/src/store/index.ts +++ b/packages/core/src/store/index.ts @@ -40,7 +40,15 @@ const createRFStore = () => set({ nodeInternals, edges: nextEdges, hasDefaultNodes, hasDefaultEdges }); }, updateNodeDimensions: (updates: NodeDimensionUpdate[]) => { - const { onNodesChange, nodeInternals, fitViewOnInit, fitViewOnInitDone, fitViewOnInitOptions, domNode } = get(); + const { + onNodesChange, + nodeInternals, + fitViewOnInit, + fitViewOnInitDone, + fitViewOnInitOptions, + domNode, + nodeOrigin, + } = get(); const viewportNode = domNode?.querySelector('.react-flow__viewport'); if (!viewportNode) { @@ -67,8 +75,8 @@ const createRFStore = () => [internalsSymbol]: { ...node[internalsSymbol], handleBounds: { - source: getHandleBounds('.source', update.nodeElement, zoom), - target: getHandleBounds('.target', update.nodeElement, zoom), + source: getHandleBounds('.source', update.nodeElement, zoom, nodeOrigin), + target: getHandleBounds('.target', update.nodeElement, zoom, nodeOrigin), }, }, ...dimensions, diff --git a/packages/core/src/store/initialState.ts b/packages/core/src/store/initialState.ts index db6b65a8..708097bc 100644 --- a/packages/core/src/store/initialState.ts +++ b/packages/core/src/store/initialState.ts @@ -32,6 +32,7 @@ const initialState: ReactFlowStore = { domNode: null, paneDragging: false, noPanClassName: 'nopan', + nodeOrigin: [0, 0], snapGrid: [15, 15], snapToGrid: false, diff --git a/packages/core/src/types/general.ts b/packages/core/src/types/general.ts index 12b15ec5..85e8f689 100644 --- a/packages/core/src/types/general.ts +++ b/packages/core/src/types/general.ts @@ -13,6 +13,7 @@ import { NodeDragItem, NodeDragHandler, SelectionDragHandler, + NodeOrigin, } from './nodes'; import { Edge, EdgeProps, WrapEdgeProps } from './edges'; import { HandleType, StartHandle } from './handles'; @@ -149,6 +150,7 @@ export type ReactFlowStore = { maxZoom: number; translateExtent: CoordinateExtent; nodeExtent: CoordinateExtent; + nodeOrigin: NodeOrigin; nodesSelectionActive: boolean; userSelectionActive: boolean;