init commit

This commit is contained in:
iqudoo
2026-06-12 19:34:27 +08:00
commit 89b59ecc1b
38 changed files with 17719 additions and 0 deletions

View 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',
}}
/>
);
};