fix(nodeOrigin): use origin for calculating handle position
This commit is contained in:
@@ -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}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user