Files
vue-flow/examples/vite/src/EasyConnect/utils.ts
T

74 lines
2.4 KiB
TypeScript

import type { GraphNode, XYPosition } from '@vue-flow/core'
import { Position } from '@vue-flow/core'
// this helper function returns the intersection point
// of the line between the center of the intersectionNode and the target node
function getNodeIntersection(intersectionNode: GraphNode, targetNode: GraphNode) {
// https://math.stackexchange.com/questions/1724792/an-algorithm-for-finding-the-intersection-point-between-a-center-of-vision-and-a
const {
dimensions: { width: intersectionNodeWidth, height: intersectionNodeHeight },
computedPosition: intersectionNodePosition,
} = intersectionNode
const targetPosition = targetNode.computedPosition
const w = intersectionNodeWidth / 2
const h = intersectionNodeHeight / 2
const x2 = intersectionNodePosition.x + w
const y2 = intersectionNodePosition.y + h
const x1 = targetPosition.x + w
const y1 = targetPosition.y + h
const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h)
const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h)
const a = 1 / (Math.abs(xx1) + Math.abs(yy1))
const xx3 = a * xx1
const yy3 = a * yy1
const x = w * (xx3 + yy3) + x2
const y = h * (-xx3 + yy3) + y2
return { x, y }
}
// returns the position (top,right,bottom or right) passed node compared to the intersection point
function getEdgePosition(node: GraphNode, intersectionPoint: XYPosition) {
const n = { ...node.computedPosition, ...node }
const nx = Math.round(n.x)
const ny = Math.round(n.y)
const px = Math.round(intersectionPoint.x)
const py = Math.round(intersectionPoint.y)
if (px <= nx + 1) {
return Position.Left
}
if (px >= nx + n.dimensions.width - 1) {
return Position.Right
}
if (py <= ny + 1) {
return Position.Top
}
if (py >= n.y + n.dimensions.height - 1) {
return Position.Bottom
}
return Position.Top
}
// returns the parameters (sx, sy, tx, ty, sourcePos, targetPos) you need to create an edge
export function getEdgeParams(source: GraphNode, target: GraphNode) {
const sourceIntersectionPoint = getNodeIntersection(source, target)
const targetIntersectionPoint = getNodeIntersection(target, source)
const sourcePos = getEdgePosition(source, sourceIntersectionPoint)
const targetPos = getEdgePosition(target, targetIntersectionPoint)
return {
sx: sourceIntersectionPoint.x,
sy: sourceIntersectionPoint.y,
tx: targetIntersectionPoint.x,
ty: targetIntersectionPoint.y,
sourcePos,
targetPos,
}
}