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) => (