전략편집기 수정1

This commit is contained in:
Macbook
2026-06-15 01:49:33 +09:00
parent 12c556a95e
commit dbad00aa0f
4 changed files with 135 additions and 32 deletions
+54 -8
View File
@@ -57,6 +57,23 @@ let lastDragClientXY: { x: number; y: number } | null = null;
let htmlDragMouseTrackUnbind: (() => void) | null = null;
let htmlPaletteDragActive = false;
let lastHtmlDragClientXY: { x: number; y: number } | null = null;
let activeHtmlDragPayload: PaletteDragPayload | null = null;
type HtmlPaletteDropRouter = (
clientX: number,
clientY: number,
payload: PaletteDragPayload,
) => void;
let htmlDropRouter: HtmlPaletteDropRouter | null = null;
export function setHtmlPaletteDropRouter(router: HtmlPaletteDropRouter | null): void {
htmlDropRouter = router;
}
export function getActiveHtmlDragPayload(): PaletteDragPayload | null {
return activeHtmlDragPayload;
}
function installHtmlPaletteDragGlobals() {
if (typeof window === 'undefined') return;
@@ -84,7 +101,19 @@ function installHtmlPaletteDragGlobals() {
stopHtmlDragMouseTracking();
htmlPaletteDragActive = false;
lastHtmlDragClientXY = null;
activeHtmlDragPayload = null;
});
document.addEventListener('drop', (e) => {
if (!htmlPaletteDragActive) return;
e.preventDefault();
e.stopPropagation();
const payload = readPaletteHtmlDragDataFromEvent(e) ?? activeHtmlDragPayload;
if (!payload || !htmlDropRouter) return;
const x = e.clientX !== 0 || e.clientY !== 0 ? e.clientX : (lastHtmlDragClientXY?.x ?? 0);
const y = e.clientX !== 0 || e.clientY !== 0 ? e.clientY : (lastHtmlDragClientXY?.y ?? 0);
htmlDropRouter(x, y, payload);
}, true);
}
installHtmlPaletteDragGlobals();
@@ -388,6 +417,7 @@ export function startHtmlDragMouseTracking(
clientY: number,
payload: PaletteDragPayload,
): void {
activeHtmlDragPayload = payload;
stopHtmlDragMouseTracking();
if (clientX !== 0 || clientY !== 0) {
lastHtmlDragClientXY = { x: clientX, y: clientY };
@@ -418,6 +448,18 @@ export function markPaletteHtmlDragEnd(): void {
stopHtmlDragMouseTracking();
htmlPaletteDragActive = false;
lastHtmlDragClientXY = null;
activeHtmlDragPayload = null;
}
function readPaletteHtmlDragDataFromEvent(e: DragEvent): PaletteDragPayload | null {
const raw = e.dataTransfer?.getData('text/plain')
|| e.dataTransfer?.getData('application/json');
if (!raw) return null;
try {
return JSON.parse(raw) as PaletteDragPayload;
} catch {
return null;
}
}
export function getLastHtmlPaletteDragClientXY(): { x: number; y: number } | null {
@@ -429,6 +471,7 @@ export function isPaletteHtmlDragActive(): boolean {
}
export function writePaletteHtmlDragData(e: React.DragEvent, payload: PaletteDragPayload): void {
activeHtmlDragPayload = payload;
markPaletteHtmlDragStart();
const json = JSON.stringify(payload);
e.dataTransfer.setData('application/json', json);
@@ -445,17 +488,20 @@ export function isPaletteHtmlDrag(e: React.DragEvent): boolean {
}
export function readPaletteHtmlDragData(e: React.DragEvent): PaletteDragPayload | null {
const raw = e.dataTransfer.getData('text/plain')
|| e.dataTransfer.getData('application/json');
if (!raw) return null;
try {
return JSON.parse(raw) as PaletteDragPayload;
} catch {
return null;
}
return readPaletteHtmlDragDataFromEvent(e.nativeEvent) ?? activeHtmlDragPayload;
}
export function findPaletteDropKeyAtPoint(x: number, y: number): string | null {
const hosts = Array.from(document.querySelectorAll<HTMLElement>('[data-palette-drop-key]'));
for (let i = hosts.length - 1; i >= 0; i--) {
const host = hosts[i];
const key = host.dataset.paletteDropKey;
if (!key) continue;
const rect = host.getBoundingClientRect();
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
return key;
}
}
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;