@@ -4,21 +4,17 @@ import { GetState, SetState } from 'zustand';
|
||||
import { HandleElement, Node, Position, ReactFlowState } from '../../types';
|
||||
import { getDimensions } from '../../utils';
|
||||
|
||||
export const getHandleBounds = (nodeElement: HTMLDivElement, scale: number) => {
|
||||
const bounds = nodeElement.getBoundingClientRect();
|
||||
function getTranslateValues(domNode: HTMLDivElement): [number, number] {
|
||||
if (typeof window === 'undefined' || !window.DOMMatrixReadOnly) {
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
return {
|
||||
source: getHandleBoundsByHandleType('.source', nodeElement, bounds, scale),
|
||||
target: getHandleBoundsByHandleType('.target', nodeElement, bounds, scale),
|
||||
};
|
||||
};
|
||||
const style = window.getComputedStyle(domNode);
|
||||
const { m41, m42 } = new window.DOMMatrixReadOnly(style.transform);
|
||||
return [m41, m42];
|
||||
}
|
||||
|
||||
export const getHandleBoundsByHandleType = (
|
||||
selector: string,
|
||||
nodeElement: HTMLDivElement,
|
||||
parentBounds: DOMRect,
|
||||
k: number
|
||||
): HandleElement[] | null => {
|
||||
export const getHandleBounds = (selector: string, nodeElement: HTMLDivElement): HandleElement[] | null => {
|
||||
const handles = nodeElement.querySelectorAll(selector);
|
||||
|
||||
if (!handles || !handles.length) {
|
||||
@@ -28,17 +24,16 @@ export const getHandleBoundsByHandleType = (
|
||||
const handlesArray = Array.from(handles) as HTMLDivElement[];
|
||||
|
||||
return handlesArray.map((handle): HandleElement => {
|
||||
const bounds = handle.getBoundingClientRect();
|
||||
const dimensions = getDimensions(handle);
|
||||
const handleId = handle.getAttribute('data-handleid');
|
||||
const handlePosition = handle.getAttribute('data-handlepos') as unknown as Position;
|
||||
// we don't use getBoundingClientRect here, because it includes the transform of the parent (scaled viewport)
|
||||
// that we would then need to calculate out again in order to get the correct position.
|
||||
const [translateX, translateY] = getTranslateValues(handle);
|
||||
|
||||
return {
|
||||
id: handleId,
|
||||
position: handlePosition,
|
||||
x: (bounds.left - parentBounds.left) / k,
|
||||
y: (bounds.top - parentBounds.top) / k,
|
||||
...dimensions,
|
||||
id: handle.getAttribute('data-handleid'),
|
||||
position: handle.getAttribute('data-handlepos') as unknown as Position,
|
||||
x: handle.offsetLeft + nodeElement.clientLeft + translateX,
|
||||
y: handle.offsetTop + nodeElement.clientTop + translateY,
|
||||
...getDimensions(handle),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
+5
-3
@@ -43,7 +43,7 @@ const createStore = () =>
|
||||
set({ nodeInternals, edges: nextEdges, hasDefaultNodes, hasDefaultEdges });
|
||||
},
|
||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => {
|
||||
const { onNodesChange, transform, nodeInternals, fitViewOnInit, fitViewOnInitDone, fitViewOnInitOptions } = get();
|
||||
const { onNodesChange, nodeInternals, fitViewOnInit, fitViewOnInitDone, fitViewOnInitOptions } = get();
|
||||
|
||||
const changes: NodeDimensionChange[] = updates.reduce<NodeDimensionChange[]>((res, update) => {
|
||||
const node = nodeInternals.get(update.id);
|
||||
@@ -57,12 +57,14 @@ const createStore = () =>
|
||||
);
|
||||
|
||||
if (doUpdate) {
|
||||
const handleBounds = getHandleBounds(update.nodeElement, transform[2]);
|
||||
nodeInternals.set(node.id, {
|
||||
...node,
|
||||
[internalsSymbol]: {
|
||||
...node[internalsSymbol],
|
||||
handleBounds,
|
||||
handleBounds: {
|
||||
source: getHandleBounds('.source', update.nodeElement),
|
||||
target: getHandleBounds('.target', update.nodeElement),
|
||||
},
|
||||
},
|
||||
...dimensions,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user