Skip to Content
ExamplesNodes

Easy Connect

Fed up with tiny little connection handles? Make your whole node act as one! Keep in mind though that you need to define separate drag handles in this case to still be able to drag the node.

import type { InternalNode } from '@xyflow/vue'; import { Position } from '@xyflow/vue'; // returns the intersection point of the line between the center of intersectionNode and the target node // https://math.stackexchange.com/questions/1724792 function getNodeIntersection(intersectionNode: InternalNode, targetNode: InternalNode) { const intersectionNodeWidth = intersectionNode.measured.width ?? 0; const intersectionNodeHeight = intersectionNode.measured.height ?? 0; const intersectionNodePosition = intersectionNode.internals.positionAbsolute; const targetPosition = targetNode.internals.positionAbsolute; const w = intersectionNodeWidth / 2; const h = intersectionNodeHeight / 2; const x2 = intersectionNodePosition.x + w; const y2 = intersectionNodePosition.y + h; const x1 = targetPosition.x + (targetNode.measured.width ?? 0) / 2; const y1 = targetPosition.y + (targetNode.measured.height ?? 0) / 2; 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) || 1); 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 Left) of the node relative to the intersection point function getEdgePosition(node: InternalNode, intersectionPoint: { x: number; y: number }) { const pos = node.internals.positionAbsolute; const nx = Math.round(pos.x); const ny = Math.round(pos.y); const px = Math.round(intersectionPoint.x); const py = Math.round(intersectionPoint.y); const width = node.measured.width ?? 0; const height = node.measured.height ?? 0; if (px <= nx + 1) { return Position.Left; } if (px >= nx + width - 1) { return Position.Right; } if (py <= ny + 1) { return Position.Top; } if (py >= ny + height - 1) { return Position.Bottom; } return Position.Top; } // returns the params (sx, sy, tx, ty, sourcePos, targetPos) needed to draw a floating edge between two nodes export function getEdgeParams(source: InternalNode, target: InternalNode) { 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, }; }
Last updated on