init commit
This commit is contained in:
89
src/components/CanvasLabelImage.tsx
Normal file
89
src/components/CanvasLabelImage.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { TemplateElement } from '../types';
|
||||
import { ContentResolveMode } from '../utils';
|
||||
import { renderLabelToDataUrl } from '../labelRenderer';
|
||||
|
||||
interface CanvasLabelImageProps {
|
||||
widthMm: number;
|
||||
heightMm: number;
|
||||
elements: TemplateElement[];
|
||||
rowData: any;
|
||||
rowIndex: number;
|
||||
showBorder?: boolean;
|
||||
transparentBackground?: boolean;
|
||||
variableDefaults?: Record<string, string> | null;
|
||||
/** design=设计预览(空变量显示占位);output=排版/打印(空值隐藏图形元素) */
|
||||
mode?: ContentResolveMode;
|
||||
}
|
||||
|
||||
export const CanvasLabelImage: React.FC<CanvasLabelImageProps> = ({
|
||||
widthMm,
|
||||
heightMm,
|
||||
elements,
|
||||
rowData,
|
||||
rowIndex,
|
||||
showBorder = false,
|
||||
transparentBackground = false,
|
||||
variableDefaults = null,
|
||||
mode = 'design' as ContentResolveMode,
|
||||
}) => {
|
||||
const [dataUrl, setDataUrl] = useState<string>('');
|
||||
const [initialLoading, setInitialLoading] = useState<boolean>(true);
|
||||
|
||||
const elementsKey = useMemo(() => JSON.stringify(elements), [elements]);
|
||||
const rowDataKey = useMemo(() => JSON.stringify(rowData), [rowData]);
|
||||
|
||||
useEffect(() => {
|
||||
let active = true;
|
||||
|
||||
renderLabelToDataUrl({
|
||||
widthMm,
|
||||
heightMm,
|
||||
elements,
|
||||
rowData,
|
||||
rowIndex,
|
||||
showBorder,
|
||||
transparentBackground,
|
||||
variableDefaults,
|
||||
mode,
|
||||
})
|
||||
.then((url) => {
|
||||
if (active) {
|
||||
setDataUrl(url);
|
||||
setInitialLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Label graphics rendering error:', err);
|
||||
if (active) setInitialLoading(false);
|
||||
});
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [widthMm, heightMm, elementsKey, rowDataKey, rowIndex, showBorder, transparentBackground, mode, elements, variableDefaults]);
|
||||
|
||||
if (initialLoading && !dataUrl) {
|
||||
return (
|
||||
<div
|
||||
className="flex items-center justify-center animate-pulse text-gray-400 font-medium text-[10px] bg-transparent"
|
||||
style={{ width: '100%', height: '100%', minHeight: '30px' }}
|
||||
>
|
||||
<span>绘制中</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
src={dataUrl}
|
||||
alt="Label Preview"
|
||||
className="w-full h-full object-fill pointer-events-none select-none block"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
imageRendering: 'auto',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user