import React, { useState, useEffect, useMemo } from 'react'; import { TemplateElement } from '../types'; import { mmToPx } from '../utils'; import { renderLabelToDataUrl } from '../labelRenderer'; interface ElementFloatPreviewProps { element: TemplateElement; renderScale: number; displayZoom: number; variableDefaults?: Record | null; } /** 单元素离屏绘制(不裁切到标签页边界),用于拖动/缩放浮层 */ export const ElementFloatPreview: React.FC = ({ element, renderScale, displayZoom, variableDefaults = null, }) => { const [dataUrl, setDataUrl] = useState(''); const elementKey = useMemo(() => JSON.stringify(element), [element]); useEffect(() => { let active = true; const normalized = { ...element, x: 0, y: 0 }; renderLabelToDataUrl({ widthMm: element.width, heightMm: element.height, elements: [normalized], rowData: null, rowIndex: 0, showBorder: false, transparentBackground: true, variableDefaults, mode: 'design', scale: renderScale, }) .then((url) => { if (active) setDataUrl(url); }) .catch((err) => { console.error('Element float preview error:', err); }); return () => { active = false; }; }, [element, elementKey, renderScale, variableDefaults]); const left = mmToPx(element.x, displayZoom); const top = mmToPx(element.y, displayZoom); const width = mmToPx(element.width, displayZoom); const height = mmToPx(element.height, displayZoom); if (!dataUrl) return null; return ( ); };