+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/src/FloatingEdges/floating-edge-utils.ts b/examples/src/FloatingEdges/floating-edge-utils.ts
new file mode 100644
index 00000000..c2a881ca
--- /dev/null
+++ b/examples/src/FloatingEdges/floating-edge-utils.ts
@@ -0,0 +1,104 @@
+import { Position, MarkerType, XYPosition, GraphNode, Edge } from '@braks/vue-flow'
+
+// 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): XYPosition {
+ // 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 },
+ position: intersectionNodePosition,
+ } = intersectionNode
+ const targetPosition = targetNode.position
+
+ 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.position, ...node.dimensions }
+ 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.width - 1) {
+ return Position.Right
+ }
+ if (py <= ny + 1) {
+ return Position.Top
+ }
+ if (py >= n.y + n.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,
+ }
+}
+
+export function createElements() {
+ const win = typeof window !== 'undefined' ? window : ({} as any)
+ const elements = []
+ const center = { x: win.innerWidth / 2, y: win.innerHeight / 2 }
+
+ elements.push({ id: 'target', label: 'Target', position: center })
+
+ for (let i = 0; i < 8; i++) {
+ const degrees = i * (360 / 8)
+ const radians = degrees * (Math.PI / 180)
+ const x = 250 * Math.cos(radians) + center.x
+ const y = 250 * Math.sin(radians) + center.y
+
+ elements.push({ id: `${i}`, label: 'Source', position: { x, y } })
+
+ elements.push({
+ id: `edge-${i}`,
+ target: 'target',
+ source: `${i}`,
+ type: 'floating',
+ markerEnd: MarkerType.Arrow,
+ markerStart: {
+ id: 'markerstart',
+ type: MarkerType.Arrow,
+ orient: 'auto-start-reverse',
+ },
+ } as Edge)
+ }
+
+ return elements
+}