데스크탑 앱 수정

This commit is contained in:
Macbook
2026-06-14 22:57:37 +09:00
parent ec40241b2f
commit afd2cb2693
3 changed files with 156 additions and 104 deletions
+38 -18
View File
@@ -52,29 +52,35 @@ export function projectScreenToFlowPosition(
/** 팔레트 드롭 — 전략 빌더 캔버스 위인지 (우측 팔레트 위 release 무시) */
export function isOverStrategyBuilder(clientX: number, clientY: number): boolean {
const el = document.elementFromPoint(clientX, clientY);
if (!el) return false;
if (el.closest('.se-palette-panel, .se-side-wrap--right, .se-palette-drag-ghost')) return false;
return el.closest('.se-canvas-wrap') != null;
const elements = typeof document.elementsFromPoint === 'function'
? document.elementsFromPoint(clientX, clientY)
: [document.elementFromPoint(clientX, clientY)].filter(Boolean) as Element[];
for (const el of elements) {
if (el.closest('.se-palette-panel, .se-side-wrap--right, .se-palette-drag-ghost')) continue;
if (el.closest('.se-canvas-wrap')) return true;
}
return false;
}
/** DOM hit-test — flow 좌표 변환 오류 시에도 드롭 대상 노드 식별 */
/** DOM hit-test — elementsFromPoint 로 ghost·overlay 아래 노드까지 탐색 */
export function findFlowNodeIdAtClientPoint(clientX: number, clientY: number): string | null {
const el = document.elementFromPoint(clientX, clientY);
if (!el) return null;
const elements = typeof document.elementsFromPoint === 'function'
? document.elementsFromPoint(clientX, clientY)
: [document.elementFromPoint(clientX, clientY)].filter(Boolean) as Element[];
const nodeEl = el.closest('.react-flow__node') as HTMLElement | null;
if (nodeEl) {
const id = nodeEl.getAttribute('data-id');
if (id) return id;
for (const el of elements) {
const nodeEl = el.closest('.react-flow__node') as HTMLElement | null;
if (nodeEl) {
const id = nodeEl.getAttribute('data-id');
if (id) return id;
}
const handleEl = el.closest('[data-nodeid]') as HTMLElement | null;
if (handleEl) {
const id = handleEl.getAttribute('data-nodeid');
if (id) return id;
}
}
const handleEl = el.closest('[data-nodeid]') as HTMLElement | null;
if (handleEl) {
const id = handleEl.getAttribute('data-nodeid');
if (id) return id;
}
return null;
}
@@ -103,6 +109,20 @@ export function resolvePaletteDropClientPoint(
return { flowPos, anchorId: domId };
}
// DOM hit-test 실패 시 START 노드 bounding rect 로 보조
for (const node of nodes) {
if (!isConnectTarget(node.id)) continue;
const el = document.querySelector(`.react-flow__node[data-id="${CSS.escape(node.id)}"]`);
if (!el) continue;
const rect = el.getBoundingClientRect();
if (
clientX >= rect.left && clientX <= rect.right
&& clientY >= rect.top && clientY <= rect.bottom
) {
return { flowPos, anchorId: node.id };
}
}
const flowHit = findAtFlow(flowPos, nodes);
if (flowHit && isConnectTarget(flowHit.id)) {
return { flowPos, anchorId: flowHit.id };