refactor connection line
This commit is contained in:
@@ -4,15 +4,7 @@ import shallow from 'zustand/shallow';
|
|||||||
import { useStore } from '../../store';
|
import { useStore } from '../../store';
|
||||||
import { getBezierPath } from '../Edges/BezierEdge';
|
import { getBezierPath } from '../Edges/BezierEdge';
|
||||||
import { getSmoothStepPath } from '../Edges/SmoothStepEdge';
|
import { getSmoothStepPath } from '../Edges/SmoothStepEdge';
|
||||||
import {
|
import { ConnectionLineType, ConnectionLineComponent, HandleType, Node, ReactFlowState, Position } from '../../types';
|
||||||
HandleElement,
|
|
||||||
ConnectionLineType,
|
|
||||||
ConnectionLineComponent,
|
|
||||||
HandleType,
|
|
||||||
Node,
|
|
||||||
ReactFlowState,
|
|
||||||
Position,
|
|
||||||
} from '../../types';
|
|
||||||
import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge';
|
import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge';
|
||||||
|
|
||||||
interface ConnectionLineProps {
|
interface ConnectionLineProps {
|
||||||
@@ -29,13 +21,6 @@ interface ConnectionLineProps {
|
|||||||
|
|
||||||
const selector = (s: ReactFlowState) => ({ nodeInternals: s.nodeInternals, transform: s.transform });
|
const selector = (s: ReactFlowState) => ({ nodeInternals: s.nodeInternals, transform: s.transform });
|
||||||
|
|
||||||
const getSourceHandle = (handleId: string | null, sourceNode: Node, connectionHandleType: HandleType) => {
|
|
||||||
const handleTypeInverted = connectionHandleType === 'source' ? 'target' : 'source';
|
|
||||||
const handleBound = sourceNode.handleBounds?.[connectionHandleType] || sourceNode.handleBounds?.[handleTypeInverted];
|
|
||||||
|
|
||||||
return handleId ? handleBound?.find((d: HandleElement) => d.id === handleId) : handleBound?.[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ({
|
export default ({
|
||||||
connectionNodeId,
|
connectionNodeId,
|
||||||
connectionHandleId,
|
connectionHandleId,
|
||||||
@@ -51,28 +36,74 @@ export default ({
|
|||||||
const handleId = connectionHandleId;
|
const handleId = connectionHandleId;
|
||||||
|
|
||||||
const { nodeInternals, transform } = useStore(selector, shallow);
|
const { nodeInternals, transform } = useStore(selector, shallow);
|
||||||
const sourceNode = useRef<Node | undefined>(nodeInternals.get(nodeId));
|
const fromNode = useRef<Node | undefined>(nodeInternals.get(nodeId));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!sourceNode.current ||
|
!fromNode.current ||
|
||||||
!sourceNode.current ||
|
!fromNode.current ||
|
||||||
!isConnectable ||
|
!isConnectable ||
|
||||||
!sourceNode.current.handleBounds?.[connectionHandleType]
|
!fromNode.current.handleBounds?.[connectionHandleType]
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sourceHandle = getSourceHandle(handleId, sourceNode.current, connectionHandleType);
|
const handleBound = fromNode.current.handleBounds?.[connectionHandleType];
|
||||||
const sourceHandleX = sourceHandle ? sourceHandle.x + sourceHandle.width / 2 : (sourceNode.current?.width ?? 0) / 2;
|
const fromHandle = handleId ? handleBound?.find((d) => d.id === handleId) : handleBound?.[0];
|
||||||
const sourceHandleY = sourceHandle ? sourceHandle.y + sourceHandle.height / 2 : sourceNode.current?.height ?? 0;
|
const fromHandleX = fromHandle ? fromHandle.x + fromHandle.width / 2 : (fromNode.current?.width ?? 0) / 2;
|
||||||
const sourceX = (sourceNode.current.positionAbsolute?.x || 0) + sourceHandleX;
|
const fromHandleY = fromHandle ? fromHandle.y + fromHandle.height / 2 : fromNode.current?.height ?? 0;
|
||||||
const sourceY = (sourceNode.current.positionAbsolute?.y || 0) + sourceHandleY;
|
const fromX = (fromNode.current.positionAbsolute?.x || 0) + fromHandleX;
|
||||||
|
const fromY = (fromNode.current.positionAbsolute?.y || 0) + fromHandleY;
|
||||||
|
|
||||||
const targetX = (connectionPositionX - transform[0]) / transform[2];
|
const toX = (connectionPositionX - transform[0]) / transform[2];
|
||||||
const targetY = (connectionPositionY - transform[1]) / transform[2];
|
const toY = (connectionPositionY - transform[1]) / transform[2];
|
||||||
|
|
||||||
const isRightOrLeft = sourceHandle?.position === Position.Left || sourceHandle?.position === Position.Right;
|
const fromPostion = fromHandle?.position;
|
||||||
const targetPosition = isRightOrLeft ? Position.Left : Position.Top;
|
|
||||||
|
let toPostion: Position | undefined;
|
||||||
|
switch (fromPostion) {
|
||||||
|
case Position.Left:
|
||||||
|
toPostion = Position.Right;
|
||||||
|
break;
|
||||||
|
case Position.Right:
|
||||||
|
toPostion = Position.Left;
|
||||||
|
break;
|
||||||
|
case Position.Top:
|
||||||
|
toPostion = Position.Bottom;
|
||||||
|
break;
|
||||||
|
case Position.Bottom:
|
||||||
|
toPostion = Position.Top;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sourceX: number,
|
||||||
|
sourceY: number,
|
||||||
|
sourcePosition: Position | undefined,
|
||||||
|
targetX: number,
|
||||||
|
targetY: number,
|
||||||
|
targetPosition: Position | undefined;
|
||||||
|
|
||||||
|
switch (connectionHandleType) {
|
||||||
|
case 'source':
|
||||||
|
{
|
||||||
|
sourceX = fromX;
|
||||||
|
sourceY = fromY;
|
||||||
|
sourcePosition = fromPostion;
|
||||||
|
targetX = toX;
|
||||||
|
targetY = toY;
|
||||||
|
targetPosition = toPostion;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'target':
|
||||||
|
{
|
||||||
|
sourceX = toX;
|
||||||
|
sourceY = toY;
|
||||||
|
sourcePosition = toPostion;
|
||||||
|
targetX = fromX;
|
||||||
|
targetY = fromY;
|
||||||
|
targetPosition = fromPostion;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (CustomConnectionLineComponent) {
|
if (CustomConnectionLineComponent) {
|
||||||
return (
|
return (
|
||||||
@@ -80,14 +111,17 @@ export default ({
|
|||||||
<CustomConnectionLineComponent
|
<CustomConnectionLineComponent
|
||||||
sourceX={sourceX}
|
sourceX={sourceX}
|
||||||
sourceY={sourceY}
|
sourceY={sourceY}
|
||||||
sourcePosition={sourceHandle?.position}
|
sourcePosition={sourcePosition}
|
||||||
targetX={targetX}
|
targetX={targetX}
|
||||||
targetY={targetY}
|
targetY={targetY}
|
||||||
targetPosition={targetPosition}
|
targetPosition={targetPosition}
|
||||||
connectionLineType={connectionLineType}
|
connectionLineType={connectionLineType}
|
||||||
connectionLineStyle={connectionLineStyle}
|
connectionLineStyle={connectionLineStyle}
|
||||||
sourceNode={sourceNode.current as Node}
|
fromNode={fromNode.current}
|
||||||
sourceHandle={sourceHandle}
|
fromHandle={fromHandle}
|
||||||
|
// backward compatibility, mark as deprecated?
|
||||||
|
sourceNode={fromNode.current}
|
||||||
|
sourceHandle={fromHandle}
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
);
|
);
|
||||||
@@ -98,7 +132,7 @@ export default ({
|
|||||||
const pathParams = {
|
const pathParams = {
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
sourcePosition: sourceHandle?.position,
|
sourcePosition,
|
||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
targetPosition,
|
targetPosition,
|
||||||
|
|||||||
@@ -155,6 +155,9 @@ export type ConnectionLineComponentProps = {
|
|||||||
targetPosition?: Position;
|
targetPosition?: Position;
|
||||||
connectionLineStyle?: CSSProperties;
|
connectionLineStyle?: CSSProperties;
|
||||||
connectionLineType: ConnectionLineType;
|
connectionLineType: ConnectionLineType;
|
||||||
|
fromNode?: Node;
|
||||||
|
fromHandle?: HandleElement;
|
||||||
|
// backward compatibility, mark as deprecated?
|
||||||
sourceNode?: Node;
|
sourceNode?: Node;
|
||||||
sourceHandle?: HandleElement;
|
sourceHandle?: HandleElement;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user