fix(subflows): use abs positions for internal calculations (#2189)
* refactor(dragging): only use absolute positions * refactor(drag): handle node extent * refactor(drag-handler): return latest data * refactor(use-drag): cleanup fixes #2181
This commit is contained in:
@@ -141,7 +141,7 @@ const initialEdges: Edge[] = [
|
||||
];
|
||||
|
||||
const connectionLineStyle: CSSProperties = { stroke: '#ddd' };
|
||||
const snapGrid: SnapGrid = [16, 16];
|
||||
const snapGrid: SnapGrid = [25, 25];
|
||||
|
||||
const nodeStrokeColor = (n: Node): string => {
|
||||
if (n.style?.background) return n.style.background as string;
|
||||
@@ -203,7 +203,7 @@ const OverviewFlow = () => {
|
||||
>
|
||||
<MiniMap nodeStrokeColor={nodeStrokeColor} nodeColor={nodeColor} nodeBorderRadius={2} />
|
||||
<Controls />
|
||||
<Background color="#aaa" gap={20} />
|
||||
<Background color="#aaa" gap={25} />
|
||||
</ReactFlow>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,8 +4,8 @@ import { select } from 'd3-selection';
|
||||
|
||||
import { useStoreApi } from '../../store';
|
||||
import { pointToRendererPoint } from '../../utils/graph';
|
||||
import { NodeDragItem, NodeDragHandler, XYPosition } from '../../types';
|
||||
import { getDragItems, getEventHandlerParams, getParentNodePosition, hasSelector, updatePosition } from './utils';
|
||||
import { NodeDragItem, NodeDragHandler } from '../../types';
|
||||
import { getDragItems, getEventHandlerParams, hasSelector, updatePosition } from './utils';
|
||||
import { handleNodeClick } from '../../components/Nodes/utils';
|
||||
|
||||
export type UseDragEvent = D3DragEvent<HTMLDivElement, null, SubjectPosition>;
|
||||
@@ -40,7 +40,6 @@ function useDrag({
|
||||
const store = useStoreApi();
|
||||
const dragItems = useRef<NodeDragItem[]>();
|
||||
const lastPos = useRef<{ x: number | null; y: number | null }>({ x: null, y: null });
|
||||
const parentPos = useRef<XYPosition>({ x: 0, y: 0 });
|
||||
|
||||
// returns the pointer position projected to the RF coordinate system
|
||||
const getPointerPosition = useCallback(({ sourceEvent }: UseDragEvent) => {
|
||||
@@ -49,9 +48,6 @@ function useDrag({
|
||||
const y = sourceEvent.touches ? sourceEvent.touches[0].clientY : sourceEvent.clientY;
|
||||
const pointerPos = pointToRendererPoint({ x, y }, transform, snapToGrid, snapGrid);
|
||||
|
||||
pointerPos.x -= parentPos.current.x;
|
||||
pointerPos.y -= parentPos.current.y;
|
||||
|
||||
return pointerPos;
|
||||
}, []);
|
||||
|
||||
@@ -65,7 +61,6 @@ function useDrag({
|
||||
const dragHandler = drag()
|
||||
.on('start', (event: UseDragEvent) => {
|
||||
const { nodeInternals, multiSelectionActive, unselectNodesAndEdges } = store.getState();
|
||||
parentPos.current = getParentNodePosition(nodeInternals, nodeId);
|
||||
|
||||
if (!selectNodesOnDrag && !multiSelectionActive && nodeId) {
|
||||
if (!nodeInternals.get(nodeId)?.selected) {
|
||||
|
||||
@@ -21,16 +21,6 @@ export function isParentSelected(node: Node, nodeInternals: NodeInternals): bool
|
||||
return isParentSelected(parentNode, nodeInternals);
|
||||
}
|
||||
|
||||
export function getParentNodePosition(nodeInternals: NodeInternals, nodeId?: string): XYPosition {
|
||||
const parentNodeId = nodeId ? nodeInternals.get(nodeId)?.parentNode : null;
|
||||
const parentNode = parentNodeId ? nodeInternals.get(parentNodeId) : null;
|
||||
|
||||
return {
|
||||
x: parentNode?.positionAbsolute?.x || 0,
|
||||
y: parentNode?.positionAbsolute?.y || 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function hasSelector(target: Element, selector: string, nodeRef: RefObject<Element>): boolean {
|
||||
let current = target;
|
||||
|
||||
@@ -49,10 +39,10 @@ export function getDragItems(nodeInternals: NodeInternals, mousePos: XYPosition,
|
||||
.filter((n) => (n.selected || n.id === nodeId) && (!n.parentNode || !isParentSelected(n, nodeInternals)))
|
||||
.map((n) => ({
|
||||
id: n.id,
|
||||
position: n.position,
|
||||
position: n.positionAbsolute || { x: 0, y: 0 },
|
||||
distance: {
|
||||
x: mousePos.x - n.position.x,
|
||||
y: mousePos.y - n.position.y,
|
||||
x: mousePos.x - (n.positionAbsolute?.x ?? 0),
|
||||
y: mousePos.y - (n.positionAbsolute?.y ?? 0),
|
||||
},
|
||||
delta: {
|
||||
x: 0,
|
||||
@@ -72,16 +62,19 @@ export function updatePosition(
|
||||
nodeExtent?: CoordinateExtent
|
||||
): NodeDragItem {
|
||||
let currentExtent = dragItem.extent || nodeExtent;
|
||||
let nextPosition = { x: mousePos.x - dragItem.distance.x, y: mousePos.y - dragItem.distance.y };
|
||||
const nextPosition = { x: mousePos.x - dragItem.distance.x, y: mousePos.y - dragItem.distance.y };
|
||||
|
||||
if (dragItem.extent === 'parent') {
|
||||
if (dragItem.parentNode && dragItem.width && dragItem.height) {
|
||||
const parent = nodeInternals.get(dragItem.parentNode);
|
||||
currentExtent =
|
||||
parent?.width && parent?.height
|
||||
parent?.positionAbsolute && parent?.width && parent?.height
|
||||
? [
|
||||
[0, 0],
|
||||
[parent.width - dragItem.width, parent.height - dragItem.height],
|
||||
[parent.positionAbsolute.x, parent.positionAbsolute.y],
|
||||
[
|
||||
parent.positionAbsolute.x + parent.width - dragItem.width,
|
||||
parent.positionAbsolute.y + parent.height - dragItem.height,
|
||||
],
|
||||
]
|
||||
: currentExtent;
|
||||
} else {
|
||||
@@ -93,13 +86,7 @@ export function updatePosition(
|
||||
}
|
||||
}
|
||||
|
||||
nextPosition = currentExtent ? clampPosition(nextPosition, currentExtent as CoordinateExtent) : nextPosition;
|
||||
|
||||
dragItem.delta = {
|
||||
x: nextPosition.x - dragItem.position.x,
|
||||
y: nextPosition.y - dragItem.position.y,
|
||||
};
|
||||
dragItem.position = nextPosition;
|
||||
dragItem.position = currentExtent ? clampPosition(nextPosition, currentExtent as CoordinateExtent) : nextPosition;
|
||||
|
||||
return dragItem;
|
||||
}
|
||||
@@ -121,11 +108,6 @@ export function getEventHandlerParams({
|
||||
|
||||
return {
|
||||
...node,
|
||||
position: n.position,
|
||||
positionAbsolute: {
|
||||
x: (node.positionAbsolute?.x || 0) + n.delta.x,
|
||||
y: (node.positionAbsolute?.y || 0) + n.delta.y,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -99,7 +99,16 @@ const createStore = () =>
|
||||
};
|
||||
|
||||
if (positionChanged) {
|
||||
change.positionAbsolute = node.position;
|
||||
change.position = node.position;
|
||||
|
||||
if (node.parentNode) {
|
||||
const parentNode = nodeInternals.get(node.parentNode);
|
||||
change.position = {
|
||||
x: change.position.x - (parentNode?.positionAbsolute?.x ?? 0),
|
||||
y: change.position.y - (parentNode?.positionAbsolute?.y ?? 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return change;
|
||||
|
||||
@@ -12,6 +12,7 @@ export type NodePositionChange = {
|
||||
id: string;
|
||||
type: 'position';
|
||||
position?: XYPosition;
|
||||
positionAbsolute?: XYPosition;
|
||||
dragging?: boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -115,8 +115,6 @@ export type NodeDragItem = {
|
||||
position: XYPosition;
|
||||
// distance from the mouse cursor to the node when start dragging
|
||||
distance: XYPosition;
|
||||
// delta to previous position
|
||||
delta: XYPosition;
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
extent?: 'parent' | CoordinateExtent;
|
||||
|
||||
@@ -67,6 +67,10 @@ function applyChanges(changes: any[], elements: any[]): any[] {
|
||||
updateItem.position = currentChange.position;
|
||||
}
|
||||
|
||||
if (typeof currentChange.positionAbsolute !== 'undefined') {
|
||||
updateItem.positionAbsolute = currentChange.positionAbsolute;
|
||||
}
|
||||
|
||||
if (typeof currentChange.dragging !== 'undefined') {
|
||||
updateItem.dragging = currentChange.dragging;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user