리포트 관리 중간 병합 #90
|
|
@ -20,6 +20,8 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
|
|||
snapValueToGrid,
|
||||
calculateAlignmentGuides,
|
||||
clearAlignmentGuides,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
} = useReportDesigner();
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [isResizing, setIsResizing] = useState(false);
|
||||
|
|
@ -96,8 +98,20 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
|
|||
if (isDragging) {
|
||||
const newX = Math.max(0, e.clientX - dragStart.x);
|
||||
const newY = Math.max(0, e.clientY - dragStart.y);
|
||||
const snappedX = snapValueToGrid(newX);
|
||||
const snappedY = snapValueToGrid(newY);
|
||||
|
||||
// 캔버스 경계 체크 (mm를 px로 변환: 1mm ≈ 3.7795px)
|
||||
const canvasWidthPx = canvasWidth * 3.7795;
|
||||
const canvasHeightPx = canvasHeight * 3.7795;
|
||||
|
||||
// 컴포넌트가 캔버스 안에 있도록 제한
|
||||
const maxX = canvasWidthPx - component.width;
|
||||
const maxY = canvasHeightPx - component.height;
|
||||
|
||||
const boundedX = Math.min(Math.max(0, newX), maxX);
|
||||
const boundedY = Math.min(Math.max(0, newY), maxY);
|
||||
|
||||
const snappedX = snapValueToGrid(boundedX);
|
||||
const snappedY = snapValueToGrid(boundedY);
|
||||
|
||||
// 정렬 가이드라인 계산
|
||||
calculateAlignmentGuides(component.id, snappedX, snappedY, component.width, component.height);
|
||||
|
|
@ -116,9 +130,16 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
|
|||
if (isGrouped) {
|
||||
components.forEach((c) => {
|
||||
if (c.groupId === component.groupId && c.id !== component.id) {
|
||||
const newGroupX = c.x + deltaX;
|
||||
const newGroupY = c.y + deltaY;
|
||||
|
||||
// 그룹 컴포넌트도 경계 체크
|
||||
const groupMaxX = canvasWidthPx - c.width;
|
||||
const groupMaxY = canvasHeightPx - c.height;
|
||||
|
||||
updateComponent(c.id, {
|
||||
x: c.x + deltaX,
|
||||
y: c.y + deltaY,
|
||||
x: Math.min(Math.max(0, newGroupX), groupMaxX),
|
||||
y: Math.min(Math.max(0, newGroupY), groupMaxY),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -128,10 +149,22 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
|
|||
const deltaY = e.clientY - resizeStart.y;
|
||||
const newWidth = Math.max(50, resizeStart.width + deltaX);
|
||||
const newHeight = Math.max(30, resizeStart.height + deltaY);
|
||||
|
||||
// 캔버스 경계 체크
|
||||
const canvasWidthPx = canvasWidth * 3.7795;
|
||||
const canvasHeightPx = canvasHeight * 3.7795;
|
||||
|
||||
// 컴포넌트가 캔버스를 벗어나지 않도록 최대 크기 제한
|
||||
const maxWidth = canvasWidthPx - component.x;
|
||||
const maxHeight = canvasHeightPx - component.y;
|
||||
|
||||
const boundedWidth = Math.min(newWidth, maxWidth);
|
||||
const boundedHeight = Math.min(newHeight, maxHeight);
|
||||
|
||||
// Grid Snap 적용
|
||||
updateComponent(component.id, {
|
||||
width: snapValueToGrid(newWidth),
|
||||
height: snapValueToGrid(newHeight),
|
||||
width: snapValueToGrid(boundedWidth),
|
||||
height: snapValueToGrid(boundedHeight),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -171,6 +204,8 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
|
|||
snapValueToGrid,
|
||||
calculateAlignmentGuides,
|
||||
clearAlignmentGuides,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
]);
|
||||
|
||||
// 표시할 값 결정
|
||||
|
|
|
|||
|
|
@ -265,9 +265,9 @@ export function ReportDesignerCanvas() {
|
|||
<div className="border-b bg-white px-4 py-2 text-center text-sm font-medium text-gray-700">작업 영역</div>
|
||||
|
||||
{/* 캔버스 스크롤 영역 */}
|
||||
<div className="flex-1 overflow-auto p-8">
|
||||
<div className="flex flex-1 items-center justify-center overflow-auto p-8">
|
||||
{/* 눈금자와 캔버스를 감싸는 컨테이너 */}
|
||||
<div className="mx-auto inline-flex flex-col">
|
||||
<div className="inline-flex flex-col">
|
||||
{/* 좌상단 코너 + 가로 눈금자 */}
|
||||
{showRuler && (
|
||||
<div className="flex">
|
||||
|
|
|
|||
Loading…
Reference in New Issue