import type { AgentPsdTemplateReplaceMode } from "@/lib/agents/psd-template-config"; export interface AgentPsdImagePlacement { scale: number; offsetX: number; offsetY: number; } export interface AgentPsdImageSize { width: number; height: number; } export function getDefaultAgentPsdImagePlacement(): AgentPsdImagePlacement { return { scale: 1, offsetX: 0, offsetY: 0, }; } export function normalizeAgentPsdImagePlacement( value: Partial | null | undefined ): AgentPsdImagePlacement { const scale = Number(value?.scale); const offsetX = Number(value?.offsetX); const offsetY = Number(value?.offsetY); return { scale: Number.isFinite(scale) && scale > 0 ? Math.max(0.1, Math.min(8, scale)) : 1, offsetX: Number.isFinite(offsetX) ? offsetX : 0, offsetY: Number.isFinite(offsetY) ? offsetY : 0, }; } function resolveBaseFittedSize(params: { containerWidth: number; containerHeight: number; imageWidth: number; imageHeight: number; replaceMode: AgentPsdTemplateReplaceMode; }) { const { containerWidth, containerHeight, imageWidth, imageHeight, replaceMode } = params; const safeImageWidth = Math.max(1, imageWidth); const safeImageHeight = Math.max(1, imageHeight); if (replaceMode === "stretch") { return { width: containerWidth, height: containerHeight, left: 0, top: 0, }; } const fitRatio = replaceMode === "contain" ? Math.min(containerWidth / safeImageWidth, containerHeight / safeImageHeight) : Math.max(containerWidth / safeImageWidth, containerHeight / safeImageHeight); const width = safeImageWidth * fitRatio; const height = safeImageHeight * fitRatio; return { width, height, left: (containerWidth - width) / 2, top: (containerHeight - height) / 2, }; } export function resolveAgentPsdImagePlacementFrame(params: { containerWidth: number; containerHeight: number; imageWidth: number; imageHeight: number; replaceMode: AgentPsdTemplateReplaceMode; placement?: Partial | null; }) { const { containerWidth, containerHeight, imageWidth, imageHeight, replaceMode } = params; const placement = normalizeAgentPsdImagePlacement(params.placement); const baseFrame = resolveBaseFittedSize({ containerWidth, containerHeight, imageWidth, imageHeight, replaceMode, }); const width = baseFrame.width * placement.scale; const height = baseFrame.height * placement.scale; const left = baseFrame.left - (width - baseFrame.width) / 2 + placement.offsetX; const top = baseFrame.top - (height - baseFrame.height) / 2 + placement.offsetY; return { width, height, left, top, }; }