전략편집기 수정

This commit is contained in:
Macbook
2026-06-14 23:56:27 +09:00
parent 198ebbb3d7
commit 55a517ba1c
5 changed files with 163 additions and 13 deletions
@@ -72,6 +72,14 @@ export function projectScreenToFlowPosition(
);
}
/** 목록 방식 편집기 위인지 */
export function isOverListEditor(clientX: number, clientY: number): boolean {
for (const el of elementsUnderDragPoint(clientX, clientY)) {
if (el.closest('.se-list-editor')) return true;
}
return false;
}
/** 팔레트 드롭 — 전략 빌더 캔버스 위인지 */
export function isOverStrategyBuilder(clientX: number, clientY: number): boolean {
for (const el of elementsUnderDragPoint(clientX, clientY)) {
+22 -5
View File
@@ -1,6 +1,7 @@
/**
* Desktop(Tauri) — HTML5 DnD 대신 pointer + 전체화면 overlay 드래그
*/
import { elementsUnderDragPoint } from './flowScreenProjection';
import { isDesktop } from './platform';
export type PaletteDragPayload = Record<string, unknown> & {
@@ -43,6 +44,8 @@ let overlayController: OverlayController | null = null;
let overlayElement: HTMLElement | null = null;
let listeners = new Set<PaletteDragListener>();
let dropHandler: PaletteDropHandler | null = null;
let moveRafId: number | null = null;
let pendingMove: { x: number; y: number } | null = null;
export function needsPointerPaletteDrag(): boolean {
return isDesktop();
@@ -88,6 +91,11 @@ function dispatchEnd(xy: { x: number; y: number }, payload: PaletteDragPayload)
function cleanupDrag() {
activePayload = null;
activePointerId = null;
pendingMove = null;
if (moveRafId != null) {
cancelAnimationFrame(moveRafId);
moveRafId = null;
}
document.body.classList.remove('se-palette-drag-active');
overlayController?.unmount();
document.querySelectorAll('.se-palette-drag-ghost').forEach(el => el.remove());
@@ -107,7 +115,15 @@ function finishDrag(phase: 'end' | 'cancel', xy: { x: number; y: number }) {
export function notifyPaletteDragMove(clientX: number, clientY: number) {
if (!activePayload) return;
emit({ phase: 'move', x: clientX, y: clientY, payload: activePayload });
pendingMove = { x: clientX, y: clientY };
if (moveRafId != null) return;
moveRafId = requestAnimationFrame(() => {
moveRafId = null;
if (!pendingMove || !activePayload) return;
const { x, y } = pendingMove;
pendingMove = null;
emit({ phase: 'move', x, y, payload: activePayload });
});
}
export function notifyPaletteDragEnd(clientX: number, clientY: number) {
@@ -229,8 +245,9 @@ export function readPaletteHtmlDragData(e: React.DragEvent): PaletteDragPayload
}
export function findPaletteDropKeyAtPoint(x: number, y: number): string | null {
const el = document.elementFromPoint(x, y);
if (!el) return null;
const host = el.closest('[data-palette-drop-key]') as HTMLElement | null;
return host?.dataset.paletteDropKey ?? null;
for (const el of elementsUnderDragPoint(x, y)) {
const host = el.closest('[data-palette-drop-key]') as HTMLElement | null;
if (host?.dataset.paletteDropKey) return host.dataset.paletteDropKey;
}
return null;
}