fix(nodeOrigin): use origin for calculating handle position

This commit is contained in:
moklick
2022-09-01 12:37:13 +02:00
parent 2172522a0b
commit 23fdd20658
6 changed files with 27 additions and 7 deletions
+9 -4
View File
@@ -1,13 +1,14 @@
import { MouseEvent } from 'react'; import { MouseEvent } from 'react';
import { StoreApi } from 'zustand'; import { StoreApi } from 'zustand';
import { HandleElement, Node, Position, ReactFlowState } from '../../types'; import { HandleElement, Node, NodeOrigin, Position, ReactFlowState } from '../../types';
import { getDimensions } from '../../utils'; import { getDimensions } from '../../utils';
export const getHandleBounds = ( export const getHandleBounds = (
selector: string, selector: string,
nodeElement: HTMLDivElement, nodeElement: HTMLDivElement,
zoom: number zoom: number,
nodeOrigin: NodeOrigin
): HandleElement[] | null => { ): HandleElement[] | null => {
const handles = nodeElement.querySelectorAll(selector); const handles = nodeElement.querySelectorAll(selector);
@@ -17,6 +18,10 @@ export const getHandleBounds = (
const handlesArray = Array.from(handles) as HTMLDivElement[]; const handlesArray = Array.from(handles) as HTMLDivElement[];
const nodeBounds = nodeElement.getBoundingClientRect(); const nodeBounds = nodeElement.getBoundingClientRect();
const nodeOffset = {
x: nodeBounds.width * nodeOrigin[0],
y: nodeBounds.height * nodeOrigin[1],
};
return handlesArray.map((handle): HandleElement => { return handlesArray.map((handle): HandleElement => {
const handleBounds = handle.getBoundingClientRect(); const handleBounds = handle.getBoundingClientRect();
@@ -24,8 +29,8 @@ export const getHandleBounds = (
return { return {
id: handle.getAttribute('data-handleid'), id: handle.getAttribute('data-handleid'),
position: handle.getAttribute('data-handlepos') as unknown as Position, position: handle.getAttribute('data-handlepos') as unknown as Position,
x: (handleBounds.left - nodeBounds.left) / zoom, x: (handleBounds.left - nodeBounds.left - nodeOffset.x) / zoom,
y: (handleBounds.top - nodeBounds.top) / zoom, y: (handleBounds.top - nodeBounds.top - nodeOffset.y) / zoom,
...getDimensions(handle), ...getDimensions(handle),
}; };
}); });
@@ -41,6 +41,7 @@ type StoreUpdaterProps = Pick<
| 'onSelectionDrag' | 'onSelectionDrag'
| 'onSelectionDragStop' | 'onSelectionDragStop'
| 'noPanClassName' | 'noPanClassName'
| 'nodeOrigin'
>; >;
const selector = (s: ReactFlowState) => ({ const selector = (s: ReactFlowState) => ({
@@ -110,6 +111,7 @@ const StoreUpdater = ({
onSelectionDragStart, onSelectionDragStart,
onSelectionDragStop, onSelectionDragStop,
noPanClassName, noPanClassName,
nodeOrigin,
}: StoreUpdaterProps) => { }: StoreUpdaterProps) => {
const { const {
setNodes, setNodes,
@@ -157,6 +159,7 @@ const StoreUpdater = ({
useDirectStoreUpdater('onSelectionDragStart', onSelectionDragStart, store.setState); useDirectStoreUpdater('onSelectionDragStart', onSelectionDragStart, store.setState);
useDirectStoreUpdater('onSelectionDragStop', onSelectionDragStop, store.setState); useDirectStoreUpdater('onSelectionDragStop', onSelectionDragStop, store.setState);
useDirectStoreUpdater('noPanClassName', noPanClassName, store.setState); useDirectStoreUpdater('noPanClassName', noPanClassName, store.setState);
useDirectStoreUpdater('nodeOrigin', nodeOrigin, store.setState);
useStoreUpdater<Node[]>(nodes, setNodes); useStoreUpdater<Node[]>(nodes, setNodes);
useStoreUpdater<Edge[]>(edges, setEdges); useStoreUpdater<Edge[]>(edges, setEdges);
@@ -262,6 +262,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
onSelectionDragStart={onSelectionDragStart} onSelectionDragStart={onSelectionDragStart}
onSelectionDragStop={onSelectionDragStop} onSelectionDragStop={onSelectionDragStop}
noPanClassName={noPanClassName} noPanClassName={noPanClassName}
nodeOrigin={nodeOrigin}
/> />
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />} {onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
{children} {children}
+11 -3
View File
@@ -40,7 +40,15 @@ const createRFStore = () =>
set({ nodeInternals, edges: nextEdges, hasDefaultNodes, hasDefaultEdges }); set({ nodeInternals, edges: nextEdges, hasDefaultNodes, hasDefaultEdges });
}, },
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => { 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'); const viewportNode = domNode?.querySelector('.react-flow__viewport');
if (!viewportNode) { if (!viewportNode) {
@@ -67,8 +75,8 @@ const createRFStore = () =>
[internalsSymbol]: { [internalsSymbol]: {
...node[internalsSymbol], ...node[internalsSymbol],
handleBounds: { handleBounds: {
source: getHandleBounds('.source', update.nodeElement, zoom), source: getHandleBounds('.source', update.nodeElement, zoom, nodeOrigin),
target: getHandleBounds('.target', update.nodeElement, zoom), target: getHandleBounds('.target', update.nodeElement, zoom, nodeOrigin),
}, },
}, },
...dimensions, ...dimensions,
+1
View File
@@ -32,6 +32,7 @@ const initialState: ReactFlowStore = {
domNode: null, domNode: null,
paneDragging: false, paneDragging: false,
noPanClassName: 'nopan', noPanClassName: 'nopan',
nodeOrigin: [0, 0],
snapGrid: [15, 15], snapGrid: [15, 15],
snapToGrid: false, snapToGrid: false,
+2
View File
@@ -13,6 +13,7 @@ import {
NodeDragItem, NodeDragItem,
NodeDragHandler, NodeDragHandler,
SelectionDragHandler, SelectionDragHandler,
NodeOrigin,
} from './nodes'; } from './nodes';
import { Edge, EdgeProps, WrapEdgeProps } from './edges'; import { Edge, EdgeProps, WrapEdgeProps } from './edges';
import { HandleType, StartHandle } from './handles'; import { HandleType, StartHandle } from './handles';
@@ -149,6 +150,7 @@ export type ReactFlowStore = {
maxZoom: number; maxZoom: number;
translateExtent: CoordinateExtent; translateExtent: CoordinateExtent;
nodeExtent: CoordinateExtent; nodeExtent: CoordinateExtent;
nodeOrigin: NodeOrigin;
nodesSelectionActive: boolean; nodesSelectionActive: boolean;
userSelectionActive: boolean; userSelectionActive: boolean;