import React, { useState, useRef } from "react"; import { Button } from "@/components/ui/button"; import { Monitor, Smartphone, Maximize2, Minimize2 } from "lucide-react"; import { useContainerSize } from "@/hooks/useViewportSize"; interface ResponsiveScreenContainerProps { children: React.ReactNode; designWidth: number; designHeight: number; screenName?: string; } type ViewMode = "fit" | "scale" | "original" | "fullwidth"; /** * 반응형 화면 컨테이너 * 다양한 모니터 크기에 맞춰 화면을 자동 조정합니다. */ export const ResponsiveScreenContainer: React.FC = ({ children, designWidth, designHeight, screenName, }) => { const containerRef = useRef(null); const [viewMode, setViewMode] = useState("fit"); const containerSize = useContainerSize(containerRef); // 스케일 계산 (실시간 계산으로 변경) const calculateScale = (): number => { if (containerSize.width === 0 || containerSize.height === 0) return 1; let newScale = 1; switch (viewMode) { case "fit": // 컨테이너에 맞춰 비율 유지하며 조정 (여백 허용) const scaleX = (containerSize.width - 40) / designWidth; // 20px 여백 const scaleY = (containerSize.height - 40) / designHeight; // 20px 여백 newScale = Math.min(scaleX, scaleY, 1); // 최대 1배까지만 break; case "scale": // 컨테이너를 가득 채우도록 조정 (비율 유지) const fillScaleX = containerSize.width / designWidth; const fillScaleY = containerSize.height / designHeight; newScale = Math.min(fillScaleX, fillScaleY); break; case "fullwidth": // 가로폭을 컨테이너에 맞춤 (세로는 비율 유지) newScale = containerSize.width / designWidth; break; case "original": default: // 원본 크기 유지 newScale = 1; break; } return Math.max(newScale, 0.1); // 최소 0.1배 }; const scale = calculateScale(); const getViewModeInfo = (mode: ViewMode) => { switch (mode) { case "fit": return { label: "화면 맞춤", description: "모니터 크기에 맞춰 비율 유지하며 조정", icon: , }; case "scale": return { label: "전체 채움", description: "화면을 가득 채우도록 조정", icon: , }; case "fullwidth": return { label: "가로 맞춤", description: "가로폭을 화면에 맞춤", icon: , }; case "original": return { label: "원본 크기", 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: viewMode === "original" ? "auto" : "hidden", }; return (
{/* 상단 컨트롤 바 */}
{screenName && `${screenName} - `} {designWidth} × {designHeight} (배율: {Math.round(scale * 100)}% | 사용 가능: {containerSize.width}×{containerSize.height})
{(["fit", "scale", "fullwidth", "original"] as ViewMode[]).map((mode) => { const info = getViewModeInfo(mode); return ( ); })}
{/* 화면 컨텐츠 영역 */}
{children}
); }; export default ResponsiveScreenContainer;