Draw canvas connections in screen overlay
This commit is contained in:
@@ -11,8 +11,8 @@ import {
|
||||
Position,
|
||||
ReactFlow,
|
||||
ReactFlowProvider,
|
||||
ViewportPortal,
|
||||
useReactFlow,
|
||||
useViewport,
|
||||
type Connection,
|
||||
type Edge,
|
||||
type EdgeChange,
|
||||
@@ -725,11 +725,26 @@ function clampViewport(viewport: FlowViewport, minZoom: number, maxZoom: number)
|
||||
};
|
||||
}
|
||||
|
||||
function buildConnectionPath(source: CanvasNode, target: CanvasNode) {
|
||||
const sourceX = source.x + source.width + 8;
|
||||
const sourceY = source.y + source.height / 2;
|
||||
const targetX = target.x - 8;
|
||||
const targetY = target.y + target.height / 2;
|
||||
function flowToScreen(point: { x: number; y: number }, viewport: CanvasViewport) {
|
||||
return {
|
||||
x: point.x * viewport.zoom + viewport.x,
|
||||
y: point.y * viewport.zoom + viewport.y,
|
||||
};
|
||||
}
|
||||
|
||||
function buildConnectionPath(source: CanvasNode, target: CanvasNode, viewport: CanvasViewport) {
|
||||
const sourcePoint = flowToScreen({
|
||||
x: source.x + source.width + 8,
|
||||
y: source.y + source.height / 2,
|
||||
}, viewport);
|
||||
const targetPoint = flowToScreen({
|
||||
x: target.x - 8,
|
||||
y: target.y + target.height / 2,
|
||||
}, viewport);
|
||||
const sourceX = sourcePoint.x;
|
||||
const sourceY = sourcePoint.y;
|
||||
const targetX = targetPoint.x;
|
||||
const targetY = targetPoint.y;
|
||||
const distance = Math.max(80, Math.abs(targetX - sourceX) * 0.45);
|
||||
return `M ${sourceX} ${sourceY} C ${sourceX + distance} ${sourceY}, ${targetX - distance} ${targetY}, ${targetX} ${targetY}`;
|
||||
}
|
||||
@@ -745,6 +760,7 @@ function CanvasConnectionOverlay({
|
||||
edgeStroke: string;
|
||||
edgeZIndex: number;
|
||||
}) {
|
||||
const viewport = useViewport();
|
||||
const nodeMap = useMemo(() => new Map(nodes.map(node => [node.id, node])), [nodes]);
|
||||
const visibleConnections = connections
|
||||
.map(connection => {
|
||||
@@ -757,49 +773,46 @@ function CanvasConnectionOverlay({
|
||||
if (visibleConnections.length === 0) return null;
|
||||
|
||||
return (
|
||||
<ViewportPortal>
|
||||
<svg
|
||||
className="canvas-connection-overlay"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 1,
|
||||
height: 1,
|
||||
overflow: 'visible',
|
||||
pointerEvents: 'none',
|
||||
zIndex: edgeZIndex,
|
||||
}}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<defs>
|
||||
<marker
|
||||
id="canvas-connection-arrow"
|
||||
markerWidth="12"
|
||||
markerHeight="12"
|
||||
refX="10"
|
||||
refY="6"
|
||||
orient="auto"
|
||||
markerUnits="strokeWidth"
|
||||
>
|
||||
<path d="M 2 2 L 10 6 L 2 10 z" fill={edgeStroke} />
|
||||
</marker>
|
||||
</defs>
|
||||
{visibleConnections.map(({ connection, source, target }) => (
|
||||
<path
|
||||
key={connection.id}
|
||||
d={buildConnectionPath(source, target)}
|
||||
fill="none"
|
||||
stroke={edgeStroke}
|
||||
strokeWidth={3}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
markerEnd="url(#canvas-connection-arrow)"
|
||||
opacity={0.95}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
</ViewportPortal>
|
||||
<svg
|
||||
className="canvas-connection-overlay"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
overflow: 'visible',
|
||||
pointerEvents: 'none',
|
||||
zIndex: edgeZIndex,
|
||||
}}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<defs>
|
||||
<marker
|
||||
id="canvas-connection-arrow"
|
||||
markerWidth="12"
|
||||
markerHeight="12"
|
||||
refX="10"
|
||||
refY="6"
|
||||
orient="auto"
|
||||
markerUnits="strokeWidth"
|
||||
>
|
||||
<path d="M 2 2 L 10 6 L 2 10 z" fill={edgeStroke} />
|
||||
</marker>
|
||||
</defs>
|
||||
{visibleConnections.map(({ connection, source, target }) => (
|
||||
<path
|
||||
key={connection.id}
|
||||
d={buildConnectionPath(source, target, viewport)}
|
||||
fill="none"
|
||||
stroke={edgeStroke}
|
||||
strokeWidth={3}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
markerEnd="url(#canvas-connection-arrow)"
|
||||
opacity={0.95}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user