mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-04 14:55:34 +00:00
77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import { Position, internalsSymbol } from 'reactflow';
|
|
|
|
// returns the position (top,right,bottom or right) passed node compared to
|
|
function getParams(nodeA, nodeB) {
|
|
const centerA = getNodeCenter(nodeA);
|
|
const centerB = getNodeCenter(nodeB);
|
|
|
|
const horizontalDiff = Math.abs(centerA.x - centerB.x);
|
|
const verticalDiff = Math.abs(centerA.y - centerB.y);
|
|
|
|
let position: Position;
|
|
|
|
// when the horizontal difference between the nodes is bigger, we use Position.Left or Position.Right for the handle
|
|
if (horizontalDiff > verticalDiff) {
|
|
position = centerA.x > centerB.x ? Position.Left : Position.Right;
|
|
} else {
|
|
// here the vertical difference between the nodes is bigger, so we use Position.Top or Position.Bottom for the handle
|
|
position = centerA.y > centerB.y ? Position.Top : Position.Bottom;
|
|
}
|
|
|
|
const [x, y] = getHandleCoordsByPosition(nodeA, position);
|
|
return [x, y, position];
|
|
}
|
|
|
|
function getHandleCoordsByPosition(node, handlePosition) {
|
|
// all handles are from type source, that's why we use handleBounds.source here
|
|
const handle = node[internalsSymbol].handleBounds.source.find(h => h.position === handlePosition);
|
|
|
|
let offsetX = handle.width / 2;
|
|
let offsetY = handle.height / 2;
|
|
|
|
// this is a tiny detail to make the markerEnd of an edge visible.
|
|
// The handle position that gets calculated has the origin top-left, so depending which side we are using, we add a little offset
|
|
// when the handlePosition is Position.Right for example, we need to add an offset as big as the handle itself in order to get the correct position
|
|
switch (handlePosition) {
|
|
case Position.Left:
|
|
offsetX = 0;
|
|
break;
|
|
case Position.Right:
|
|
offsetX = handle.width;
|
|
break;
|
|
case Position.Top:
|
|
offsetY = 0;
|
|
break;
|
|
case Position.Bottom:
|
|
offsetY = handle.height;
|
|
break;
|
|
}
|
|
|
|
const x = node.positionAbsolute.x + handle.x + offsetX;
|
|
const y = node.positionAbsolute.y + handle.y + offsetY;
|
|
|
|
return [x, y];
|
|
}
|
|
|
|
function getNodeCenter(node) {
|
|
return {
|
|
x: node.positionAbsolute.x + node.width / 2,
|
|
y: node.positionAbsolute.y + node.height / 2,
|
|
};
|
|
}
|
|
|
|
// returns the parameters (sx, sy, tx, ty, sourcePos, targetPos) you need to create an edge
|
|
export function getEdgeParams(source, target) {
|
|
const [sx, sy, sourcePos] = getParams(source, target);
|
|
const [tx, ty, targetPos] = getParams(target, source);
|
|
|
|
return {
|
|
sx,
|
|
sy,
|
|
tx,
|
|
ty,
|
|
sourcePos,
|
|
targetPos,
|
|
};
|
|
}
|