71 lines
2.4 KiB
TypeScript
71 lines
2.4 KiB
TypeScript
import { MouseEvent as ReactMouseEvent } from 'react';
|
|
import { GetState } from 'zustand';
|
|
|
|
import { Edge, MarkerType, Position, ReactFlowState } from '../../types';
|
|
|
|
export const getMarkerEnd = (markerType?: MarkerType, markerEndId?: string): string => {
|
|
if (typeof markerEndId !== 'undefined' && markerEndId) {
|
|
return `url(#${markerEndId})`;
|
|
}
|
|
|
|
return typeof markerType !== 'undefined' ? `url(#react-flow__${markerType})` : 'none';
|
|
};
|
|
|
|
export interface GetCenterParams {
|
|
sourceX: number;
|
|
sourceY: number;
|
|
targetX: number;
|
|
targetY: number;
|
|
sourcePosition?: Position;
|
|
targetPosition?: Position;
|
|
}
|
|
|
|
const LeftOrRight = [Position.Left, Position.Right];
|
|
|
|
export const getCenter = ({
|
|
sourceX,
|
|
sourceY,
|
|
targetX,
|
|
targetY,
|
|
sourcePosition = Position.Bottom,
|
|
targetPosition = Position.Top,
|
|
}: GetCenterParams): [number, number, number, number] => {
|
|
const sourceIsLeftOrRight = LeftOrRight.includes(sourcePosition);
|
|
const targetIsLeftOrRight = LeftOrRight.includes(targetPosition);
|
|
|
|
// we expect flows to be horizontal or vertical (all handles left or right respectively top or bottom)
|
|
// a mixed edge is when one the source is on the left and the target is on the top for example.
|
|
const mixedEdge = (sourceIsLeftOrRight && !targetIsLeftOrRight) || (targetIsLeftOrRight && !sourceIsLeftOrRight);
|
|
|
|
if (mixedEdge) {
|
|
const xOffset = sourceIsLeftOrRight ? Math.abs(targetX - sourceX) : 0;
|
|
const centerX = sourceX > targetX ? sourceX - xOffset : sourceX + xOffset;
|
|
|
|
const yOffset = sourceIsLeftOrRight ? 0 : Math.abs(targetY - sourceY);
|
|
const centerY = sourceY < targetY ? sourceY + yOffset : sourceY - yOffset;
|
|
|
|
return [centerX, centerY, xOffset, yOffset];
|
|
}
|
|
|
|
const xOffset = Math.abs(targetX - sourceX) / 2;
|
|
const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
|
|
|
const yOffset = Math.abs(targetY - sourceY) / 2;
|
|
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
|
|
|
return [centerX, centerY, xOffset, yOffset];
|
|
};
|
|
|
|
export function getMouseHandler(
|
|
id: string,
|
|
getState: GetState<ReactFlowState>,
|
|
handler?: (event: ReactMouseEvent<SVGGElement, MouseEvent>, edge: Edge) => void
|
|
) {
|
|
return handler === undefined
|
|
? handler
|
|
: (event: ReactMouseEvent<SVGGElement, MouseEvent>) => {
|
|
const edge = getState().edges.find((e) => e.id === id)!;
|
|
handler(event, { ...edge });
|
|
};
|
|
}
|