72 lines
2.1 KiB
TypeScript
72 lines
2.1 KiB
TypeScript
import {
|
|
getNodeDimensions,
|
|
pickSideFromPoint,
|
|
START_NODE_ID,
|
|
type HandleSide,
|
|
} from './strategyFlowLayout';
|
|
|
|
export type EdgeDragZone = 'source' | 'middle' | 'target';
|
|
|
|
/** 연결선 상 클릭/드래그 위치 → 좌(소스) / 중(경로) / 우(타겟) 구간 */
|
|
export function getEdgeDragZone(
|
|
sourceX: number,
|
|
sourceY: number,
|
|
targetX: number,
|
|
targetY: number,
|
|
pointerX: number,
|
|
pointerY: number,
|
|
): EdgeDragZone {
|
|
const dx = targetX - sourceX;
|
|
const dy = targetY - sourceY;
|
|
const len2 = dx * dx + dy * dy;
|
|
if (len2 < 4) return 'middle';
|
|
const t = ((pointerX - sourceX) * dx + (pointerY - sourceY) * dy) / len2;
|
|
const clamped = Math.max(0, Math.min(1, t));
|
|
if (clamped < 1 / 3) return 'source';
|
|
if (clamped > 2 / 3) return 'target';
|
|
return 'middle';
|
|
}
|
|
|
|
function sideToSourceHandle(side: HandleSide): string {
|
|
return `s-${side}`;
|
|
}
|
|
|
|
function sideToTargetHandle(side: HandleSide): string {
|
|
return `t-${side}`;
|
|
}
|
|
|
|
/** 드래그 위치에 맞는 소스(출발) 핸들 */
|
|
export function pickSourceHandleAtPoint(
|
|
nodeId: string,
|
|
flowPos: { x: number; y: number },
|
|
positions: Map<string, { x: number; y: number }>,
|
|
): string {
|
|
const pos = positions.get(nodeId) ?? { x: 0, y: 0 };
|
|
const dim = getNodeDimensions(nodeId);
|
|
return sideToSourceHandle(pickSideFromPoint(flowPos, pos, dim));
|
|
}
|
|
|
|
/** 드래그 위치에 맞는 타겟(도착) 핸들 */
|
|
export function pickTargetHandleAtPoint(
|
|
nodeId: string,
|
|
flowPos: { x: number; y: number },
|
|
positions: Map<string, { x: number; y: number }>,
|
|
): string {
|
|
const pos = positions.get(nodeId) ?? { x: 0, y: 0 };
|
|
const dim = getNodeDimensions(nodeId);
|
|
return sideToTargetHandle(pickSideFromPoint(flowPos, pos, dim));
|
|
}
|
|
|
|
export function buildPositionsFromNodes(
|
|
nodes: { id: string; position: { x: number; y: number } }[],
|
|
): Map<string, { x: number; y: number }> {
|
|
const map = new Map<string, { x: number; y: number }>();
|
|
for (const n of nodes) {
|
|
map.set(n.id, { x: n.position.x, y: n.position.y });
|
|
}
|
|
if (!map.has(START_NODE_ID)) {
|
|
map.set(START_NODE_ID, { x: 0, y: 220 });
|
|
}
|
|
return map;
|
|
}
|