fix(handles): calculate correct position

This commit is contained in:
moklick
2022-07-14 20:21:08 +02:00
parent c69254a80a
commit 8d866ec675
2 changed files with 14 additions and 18 deletions
+9 -16
View File
@@ -4,17 +4,11 @@ import { GetState, SetState } from 'zustand';
import { HandleElement, Node, Position, ReactFlowState } from '../../types'; import { HandleElement, Node, Position, ReactFlowState } from '../../types';
import { getDimensions } from '../../utils'; import { getDimensions } from '../../utils';
function getTranslateValues(domNode: HTMLDivElement): [number, number] { export const getHandleBounds = (
if (typeof window === 'undefined' || !window.DOMMatrixReadOnly) { selector: string,
return [0, 0]; nodeElement: HTMLDivElement,
} zoom: number
): HandleElement[] | null => {
const style = window.getComputedStyle(domNode);
const { m41, m42 } = new window.DOMMatrixReadOnly(style.transform);
return [m41, m42];
}
export const getHandleBounds = (selector: string, nodeElement: HTMLDivElement): HandleElement[] | null => {
const handles = nodeElement.querySelectorAll(selector); const handles = nodeElement.querySelectorAll(selector);
if (!handles || !handles.length) { if (!handles || !handles.length) {
@@ -22,17 +16,16 @@ export const getHandleBounds = (selector: string, nodeElement: HTMLDivElement):
} }
const handlesArray = Array.from(handles) as HTMLDivElement[]; const handlesArray = Array.from(handles) as HTMLDivElement[];
const nodeBounds = nodeElement.getBoundingClientRect();
return handlesArray.map((handle): HandleElement => { return handlesArray.map((handle): HandleElement => {
// we don't use getBoundingClientRect here, because it includes the transform of the parent (scaled viewport) const handleBounds = handle.getBoundingClientRect();
// that we would then need to calculate out again in order to get the correct position.
const [translateX, translateY] = getTranslateValues(handle);
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: handle.offsetLeft + nodeElement.clientLeft + translateX, x: (handleBounds.left - nodeBounds.left) / zoom,
y: handle.offsetTop + nodeElement.clientTop + translateY, y: (handleBounds.top - nodeBounds.top) / zoom,
...getDimensions(handle), ...getDimensions(handle),
}; };
}); });
+5 -2
View File
@@ -45,6 +45,9 @@ const createStore = () =>
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => { updateNodeDimensions: (updates: NodeDimensionUpdate[]) => {
const { onNodesChange, nodeInternals, fitViewOnInit, fitViewOnInitDone, fitViewOnInitOptions } = get(); const { onNodesChange, nodeInternals, fitViewOnInit, fitViewOnInitDone, fitViewOnInitOptions } = get();
const style = window.getComputedStyle(document.querySelector('.react-flow__viewport')!);
const { m22: zoom } = new window.DOMMatrixReadOnly(style.transform);
const changes: NodeDimensionChange[] = updates.reduce<NodeDimensionChange[]>((res, update) => { const changes: NodeDimensionChange[] = updates.reduce<NodeDimensionChange[]>((res, update) => {
const node = nodeInternals.get(update.id); const node = nodeInternals.get(update.id);
@@ -62,8 +65,8 @@ const createStore = () =>
[internalsSymbol]: { [internalsSymbol]: {
...node[internalsSymbol], ...node[internalsSymbol],
handleBounds: { handleBounds: {
source: getHandleBounds('.source', update.nodeElement), source: getHandleBounds('.source', update.nodeElement, zoom),
target: getHandleBounds('.target', update.nodeElement), target: getHandleBounds('.target', update.nodeElement, zoom),
}, },
}, },
...dimensions, ...dimensions,