"use client"; import { useMemo } from "react"; import { getFullImageUrl } from "@/lib/api/client"; import type { ImageRendererProps } from "./types"; export function ImageRenderer({ component }: ImageRendererProps) { const { imageUrl, objectFit = "contain", imageOpacity = 1, imageBorderRadius = 0, imageCaption, imageCaptionPosition = "bottom", imageCaptionFontSize = 12, imageCaptionColor = "#666666", imageCaptionAlign = "center", imageAlt = "이미지", imageRotation = 0, imageFlipH = false, imageFlipV = false, imageCropX, imageCropY, imageCropWidth, imageCropHeight, } = component; const hasCaption = !!imageCaption; const hasCrop = imageCropWidth != null && imageCropHeight != null && imageCropWidth < 100; const transformParts = useMemo(() => { const parts: string[] = []; if (imageRotation) parts.push(`rotate(${imageRotation}deg)`); if (imageFlipH) parts.push("scaleX(-1)"); if (imageFlipV) parts.push("scaleY(-1)"); return parts.length > 0 ? parts.join(" ") : undefined; }, [imageRotation, imageFlipH, imageFlipV]); const containerStyle = useMemo( () => ({ borderRadius: imageBorderRadius, overflow: "hidden" as const, }), [imageBorderRadius], ); const imageStyle = useMemo(() => { if (hasCrop) { const scaleX = 100 / (imageCropWidth ?? 100); const scaleY = 100 / (imageCropHeight ?? 100); const translateX = -(imageCropX ?? 0) * scaleX; const translateY = -(imageCropY ?? 0) * scaleY; const cropTransform = `translate(${translateX}%, ${translateY}%) scale(${scaleX}, ${scaleY})`; const extraTransform = transformParts ? ` ${transformParts}` : ""; return { display: "block" as const, width: "100%", height: "100%", objectFit: "none" as const, objectPosition: "0% 0%", opacity: imageOpacity, transform: cropTransform + extraTransform, transformOrigin: "0% 0%", }; } return { display: "block" as const, width: "100%", height: "100%", objectFit: objectFit, opacity: imageOpacity, transform: transformParts, }; }, [objectFit, imageOpacity, transformParts, hasCrop, imageCropX, imageCropY, imageCropWidth, imageCropHeight]); if (!imageUrl) { const isSmall = component.width < 100 || component.height < 80; return (