From 4e1e5b0d5108b55f0fae7d06104a464522a96227 Mon Sep 17 00:00:00 2001 From: dohyeons Date: Thu, 2 Oct 2025 14:19:38 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BA=94=EB=B2=84=EC=8A=A4=20=EC=97=AC?= =?UTF-8?q?=EB=B0=B1=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../report/designer/CanvasComponent.tsx | 31 ++++++++--- .../report/designer/ReportDesignerCanvas.tsx | 39 ++++++++++++- .../designer/ReportDesignerRightPanel.tsx | 55 ------------------- 3 files changed, 59 insertions(+), 66 deletions(-) diff --git a/frontend/components/report/designer/CanvasComponent.tsx b/frontend/components/report/designer/CanvasComponent.tsx index 504d1176..7e8e54d2 100644 --- a/frontend/components/report/designer/CanvasComponent.tsx +++ b/frontend/components/report/designer/CanvasComponent.tsx @@ -22,6 +22,7 @@ export function CanvasComponent({ component }: CanvasComponentProps) { clearAlignmentGuides, canvasWidth, canvasHeight, + margins, } = useReportDesigner(); const [isDragging, setIsDragging] = useState(false); const [isResizing, setIsResizing] = useState(false); @@ -99,16 +100,24 @@ export function CanvasComponent({ component }: CanvasComponentProps) { const newX = Math.max(0, e.clientX - dragStart.x); const newY = Math.max(0, e.clientY - dragStart.y); - // 캔버스 경계 체크 (mm를 px로 변환: 1mm ≈ 3.7795px) + // 여백을 px로 변환 (1mm ≈ 3.7795px) + const marginTopPx = margins.top * 3.7795; + const marginBottomPx = margins.bottom * 3.7795; + const marginLeftPx = margins.left * 3.7795; + const marginRightPx = margins.right * 3.7795; + + // 캔버스 경계 체크 (mm를 px로 변환) const canvasWidthPx = canvasWidth * 3.7795; const canvasHeightPx = canvasHeight * 3.7795; - // 컴포넌트가 캔버스 안에 있도록 제한 - const maxX = canvasWidthPx - component.width; - const maxY = canvasHeightPx - component.height; + // 컴포넌트가 여백 안에 있도록 제한 + const minX = marginLeftPx; + const minY = marginTopPx; + const maxX = canvasWidthPx - marginRightPx - component.width; + const maxY = canvasHeightPx - marginBottomPx - component.height; - const boundedX = Math.min(Math.max(0, newX), maxX); - const boundedY = Math.min(Math.max(0, newY), maxY); + const boundedX = Math.min(Math.max(minX, newX), maxX); + const boundedY = Math.min(Math.max(minY, newY), maxY); const snappedX = snapValueToGrid(boundedX); const snappedY = snapValueToGrid(boundedY); @@ -150,13 +159,17 @@ export function CanvasComponent({ component }: CanvasComponentProps) { const newWidth = Math.max(50, resizeStart.width + deltaX); const newHeight = Math.max(30, resizeStart.height + deltaY); + // 여백을 px로 변환 + const marginRightPx = margins.right * 3.7795; + const marginBottomPx = margins.bottom * 3.7795; + // 캔버스 경계 체크 const canvasWidthPx = canvasWidth * 3.7795; const canvasHeightPx = canvasHeight * 3.7795; - // 컴포넌트가 캔버스를 벗어나지 않도록 최대 크기 제한 - const maxWidth = canvasWidthPx - component.x; - const maxHeight = canvasHeightPx - component.y; + // 컴포넌트가 여백을 벗어나지 않도록 최대 크기 제한 + const maxWidth = canvasWidthPx - marginRightPx - component.x; + const maxHeight = canvasHeightPx - marginBottomPx - component.y; const boundedWidth = Math.min(newWidth, maxWidth); const boundedHeight = Math.min(newHeight, maxHeight); diff --git a/frontend/components/report/designer/ReportDesignerCanvas.tsx b/frontend/components/report/designer/ReportDesignerCanvas.tsx index b33e9dd4..ace87249 100644 --- a/frontend/components/report/designer/ReportDesignerCanvas.tsx +++ b/frontend/components/report/designer/ReportDesignerCanvas.tsx @@ -18,6 +18,7 @@ export function ReportDesignerCanvas() { updateComponent, canvasWidth, canvasHeight, + margins, selectComponent, selectedComponentId, selectedComponentIds, @@ -66,12 +67,33 @@ export function ReportDesignerCanvas() { height = 70; } + // 여백을 px로 변환 (1mm ≈ 3.7795px) + const marginTopPx = margins.top * 3.7795; + const marginLeftPx = margins.left * 3.7795; + const marginRightPx = margins.right * 3.7795; + const marginBottomPx = margins.bottom * 3.7795; + + // 캔버스 경계 (px) + const canvasWidthPx = canvasWidth * 3.7795; + const canvasHeightPx = canvasHeight * 3.7795; + + // 드롭 위치 계산 (여백 내부로 제한) + const rawX = x - 100; + const rawY = y - 25; + const minX = marginLeftPx; + const minY = marginTopPx; + const maxX = canvasWidthPx - marginRightPx - width; + const maxY = canvasHeightPx - marginBottomPx - height; + + const boundedX = Math.min(Math.max(minX, rawX), maxX); + const boundedY = Math.min(Math.max(minY, rawY), maxY); + // 새 컴포넌트 생성 (Grid Snap 적용) const newComponent: ComponentConfig = { id: `comp_${uuidv4()}`, type: item.componentType, - x: snapValueToGrid(Math.max(0, x - 100)), - y: snapValueToGrid(Math.max(0, y - 25)), + x: snapValueToGrid(boundedX), + y: snapValueToGrid(boundedY), width: snapValueToGrid(width), height: snapValueToGrid(height), zIndex: components.length, @@ -319,6 +341,19 @@ export function ReportDesignerCanvas() { }} onClick={handleCanvasClick} > + {/* 페이지 여백 가이드 */} + {currentPage && ( +
+ )} + {/* 정렬 가이드라인 렌더링 */} {alignmentGuides.vertical.map((x, index) => (
- - {/* 배경색 */} - - - 배경 - - -
- -
- - updatePageSettings(currentPageId, { - background_color: e.target.value, - }) - } - className="h-10 w-20" - /> - - updatePageSettings(currentPageId, { - background_color: e.target.value, - }) - } - className="flex-1" - placeholder="#ffffff" - /> -
-
- - {/* 배경색 프리셋 */} -
- {["#ffffff", "#f3f4f6", "#e5e7eb", "#d1d5db"].map((color) => ( -
-
-
) : (