import React, { useState, useRef } from "react"; import { Button } from "@/components/ui/button"; import { Monitor, Maximize2, ZoomIn, ZoomOut } from "lucide-react"; import { useContainerSize } from "@/hooks/useViewportSize"; interface ResponsiveDesignerContainerProps { children: React.ReactNode; designWidth: number; designHeight: number; screenName?: string; onScaleChange?: (scale: number) => void; } type DesignerViewMode = "fit" | "original" | "custom"; /** * 화면 디자이너용 반응형 컨테이너 * 편집 작업을 위해 원본 크기 유지하면서도 뷰포트에 맞춰 조정 가능 */ export const ResponsiveDesignerContainer: React.FC = ({ children, designWidth, designHeight, screenName, onScaleChange, }) => { const containerRef = useRef(null); const [viewMode, setViewMode] = useState("original"); const [customScale, setCustomScale] = useState(1); const containerSize = useContainerSize(containerRef); // 스케일 계산 const calculateScale = (): number => { if (containerSize.width === 0 || containerSize.height === 0) return 1; switch (viewMode) { case "fit": // 컨테이너에 맞춰 비율 유지하며 조정 (좌우 여백 16px씩 유지) const scaleX = (containerSize.width - 32) / designWidth; const scaleY = (containerSize.height - 64) / designHeight; return Math.min(scaleX, scaleY, 2); // 최대 2배까지 허용 case "custom": return customScale; case "original": default: return 1; } }; const scale = calculateScale(); // 스케일 변경 시 콜백 호출 React.useEffect(() => { onScaleChange?.(scale); }, [scale, onScaleChange]); const handleZoomIn = () => { const newScale = Math.min(customScale * 1.1, 3); setCustomScale(newScale); setViewMode("custom"); }; const handleZoomOut = () => { const newScale = Math.max(customScale * 0.9, 0.1); setCustomScale(newScale); setViewMode("custom"); }; const getViewModeInfo = (mode: DesignerViewMode) => { switch (mode) { case "fit": return { label: "화면 맞춤", description: "뷰포트에 맞춰 자동 조정", icon: , }; case "original": return { label: "원본 크기", description: "설계 해상도 100% 표시", icon: , }; case "custom": return { label: `사용자 정의 (${Math.round(customScale * 100)}%)`, description: "사용자가 조정한 배율", icon: , }; } }; const screenStyle = { width: `${designWidth}px`, height: `${designHeight}px`, transform: `scale(${scale})`, transformOrigin: "top left", transition: "transform 0.3s ease-in-out", }; const wrapperStyle = { width: `${designWidth * scale}px`, height: `${designHeight * scale}px`, overflow: "hidden", }; return (
{/* 상단 컨트롤 바 */}
{screenName && `${screenName} - `} {designWidth} × {designHeight} (배율: {Math.round(scale * 100)}% | 컨테이너: {containerSize.width}×{containerSize.height})
{/* 줌 컨트롤 */} {Math.round(scale * 100)}% {/* 뷰 모드 버튼 */} {(["fit", "original"] as DesignerViewMode[]).map((mode) => { const info = getViewModeInfo(mode); return ( ); })}
{/* 디자인 영역 */}
{children}
); }; export default ResponsiveDesignerContainer;