From c5499d2e18a59ebce88edcdf4a7ea47dbb8555fc Mon Sep 17 00:00:00 2001 From: dohyeons Date: Thu, 16 Oct 2025 11:55:14 +0900 Subject: [PATCH] =?UTF-8?q?=ED=95=B4=EC=83=81=EB=8F=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=8B=9C=20=EC=9A=94=EC=86=8C=EB=93=A4=20=EA=B0=84?= =?UTF-8?q?=EA=B2=A9=20=EC=A1=B0=EC=A0=88=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/dashboard/DashboardDesigner.tsx | 62 ++++++++++++++++--- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/frontend/components/admin/dashboard/DashboardDesigner.tsx b/frontend/components/admin/dashboard/DashboardDesigner.tsx index 60983eff..048e5172 100644 --- a/frontend/components/admin/dashboard/DashboardDesigner.tsx +++ b/frontend/components/admin/dashboard/DashboardDesigner.tsx @@ -7,7 +7,7 @@ import { DashboardTopMenu } from "./DashboardTopMenu"; import { ElementConfigModal } from "./ElementConfigModal"; import { ListWidgetConfigModal } from "./widgets/ListWidgetConfigModal"; import { DashboardElement, ElementType, ElementSubtype } from "./types"; -import { GRID_CONFIG } from "./gridUtils"; +import { GRID_CONFIG, snapToGrid, snapSizeToGrid, calculateCellSize } from "./gridUtils"; import { Resolution, RESOLUTIONS, detectScreenResolution } from "./ResolutionSelector"; interface DashboardDesignerProps { @@ -37,14 +37,58 @@ export default function DashboardDesigner({ dashboardId: initialDashboardId }: D const [screenResolution] = useState(() => detectScreenResolution()); const [resolution, setResolution] = useState(screenResolution); - // resolution λ³€κ²½ 감지 - const handleResolutionChange = useCallback((newResolution: Resolution) => { - console.log("🎯 해상도 λ³€κ²½ μš”μ²­:", newResolution); - setResolution((prev) => { - console.log("🎯 이전 해상도:", prev); - return newResolution; - }); - }, []); + // resolution λ³€κ²½ 감지 및 μš”μ†Œ μžλ™ μ‘°μ • + const handleResolutionChange = useCallback( + (newResolution: Resolution) => { + console.log("🎯 해상도 λ³€κ²½ μš”μ²­:", newResolution); + setResolution((prev) => { + console.log("🎯 이전 해상도:", prev); + + // 이전 해상도와 μƒˆ ν•΄μƒλ„μ˜ μΊ”λ²„μŠ€ λ„ˆλΉ„ λΉ„μœ¨ 계산 + const oldConfig = RESOLUTIONS[prev]; + const newConfig = RESOLUTIONS[newResolution]; + const widthRatio = newConfig.width / oldConfig.width; + + console.log("πŸ“ λ„ˆλΉ„ λΉ„μœ¨:", widthRatio, `(${oldConfig.width}px β†’ ${newConfig.width}px)`); + + // μš”μ†Œλ“€μ˜ μœ„μΉ˜μ™€ 크기λ₯Ό λΉ„μœ¨μ— 맞좰 μ‘°μ • + if (widthRatio !== 1 && elements.length > 0) { + // μƒˆ ν•΄μƒλ„μ˜ μ…€ 크기 계산 + const newCellSize = calculateCellSize(newConfig.width); + + const adjustedElements = elements.map((el) => { + // λΉ„μœ¨μ— 맞좰 μ‘°μ • (X와 λ„ˆλΉ„λ§Œ) + const scaledX = el.position.x * widthRatio; + const scaledWidth = el.size.width * widthRatio; + + // κ·Έλ¦¬λ“œμ— μŠ€λƒ… (X, Y, λ„ˆλΉ„, 높이 λͺ¨λ‘) + const snappedX = snapToGrid(scaledX, newCellSize); + const snappedY = snapToGrid(el.position.y, newCellSize); + const snappedWidth = snapSizeToGrid(scaledWidth, 2, newCellSize); + const snappedHeight = snapSizeToGrid(el.size.height, 2, newCellSize); + + return { + ...el, + position: { + x: snappedX, + y: snappedY, + }, + size: { + width: snappedWidth, + height: snappedHeight, + }, + }; + }); + + console.log("✨ μš”μ†Œ μœ„μΉ˜/크기 μžλ™ μ‘°μ • (κ·Έλ¦¬λ“œ μŠ€λƒ… 적용):", adjustedElements.length, "개"); + setElements(adjustedElements); + } + + return newResolution; + }); + }, + [elements], + ); // ν˜„μž¬ 해상도 μ„€μ • (μ•ˆμ „ν•˜κ²Œ κΈ°λ³Έκ°’ 제곡) const canvasConfig = RESOLUTIONS[resolution] || RESOLUTIONS.fhd;