fix(devtool): 元数据对象中的 tip 属性导致 JSON 序列化失败

This commit is contained in:
XcantloadX 2025-02-04 15:33:13 +08:00
parent aaef92dea3
commit 714dafc124
5 changed files with 29 additions and 6 deletions

View File

@ -169,7 +169,7 @@ function DragTool(props: ToolHandlerProps) {
onNativeMouseLeave={handleRectMouseLeave} onNativeMouseLeave={handleRectMouseLeave}
onNativeClick={(e) => handleRectClick(anno.id, e)} onNativeClick={(e) => handleRectClick(anno.id, e)}
onTransform={(points) => handleRectTransform(points, anno.id)} onTransform={(points) => handleRectTransform(points, anno.id)}
rectTip={anno.tip} rectTip={anno._tip}
showRectTip={hoveredRectId === anno.id && selectedRectId === null} showRectTip={hoveredRectId === anno.id && selectedRectId === null}
/> />
)); ));

View File

@ -297,7 +297,7 @@ const ImageEditor = React.forwardRef<ImageEditorRef, ImageEditorProps>((props, r
<RectBox <RectBox
key={rect.id} key={rect.id}
rect={Convertor.rectImage2Container(rect.data)} rect={Convertor.rectImage2Container(rect.data)}
rectTip={rect.tip} rectTip={rect._tip}
{...props} {...props}
/> />
)); ));

View File

@ -15,7 +15,7 @@ export interface Annotation {
type: AnnotationType; type: AnnotationType;
data: AnnotationTypeMap[AnnotationType]; data: AnnotationTypeMap[AnnotationType];
/** 提示信息。 */ /** 提示信息。 */
tip?: React.ReactNode; _tip?: React.ReactNode;
} }
export interface Point { export interface Point {
x: number; x: number;

View File

@ -35,8 +35,25 @@ export interface ImageMetaData {
annotations: Annotation[]; annotations: Annotation[];
} }
function fromString(data: string): ImageMetaData {
return JSON.parse(data);
}
function toString(data: ImageMetaData): string {
const replacer = (key: string, value: any) => {
if (key.startsWith('_')) {
return undefined;
}
return value;
};
return JSON.stringify(data, replacer);
}
function useImageMetaData(data?: ImageMetaData) { function useImageMetaData(data?: ImageMetaData) {
const [imageMetaData, updateImageMetaData] = useImmer<ImageMetaData>(data || { const [imageMetaData, updateImageMetaData] = useImmer<ImageMetaData>(data || {
definitions: {}, definitions: {},
annotations: [], annotations: [],
}); });
@ -117,7 +134,12 @@ function useImageMetaData(data?: ImageMetaData) {
load, load,
/** 检查是否没有任何标注和定义 */ /** 检查是否没有任何标注和定义 */
isEmpty: () => imageMetaData.annotations.length === 0 && Object.keys(imageMetaData.definitions).length === 0, isEmpty: () => imageMetaData.annotations.length === 0 && Object.keys(imageMetaData.definitions).length === 0,
/** 将图像元数据转换为字符串 */
toString,
/** 将字符串转换为图像元数据 */
fromString,
}; };
} }
export default useImageMetaData; export default useImageMetaData;

View File

@ -281,7 +281,7 @@ const usePropertyGridData = (
const ImageAnnotation: React.FC = () => { const ImageAnnotation: React.FC = () => {
const [currentTool, setCurrentTool] = useState<EditorTool>(EditorTool.Drag); const [currentTool, setCurrentTool] = useState<EditorTool>(EditorTool.Drag);
const { imageMetaData, Definitions, Annotations, clear, load } = useImageMetaData(); const { imageMetaData, Definitions, Annotations, clear, load, toString, fromString } = useImageMetaData();
const [selectedAnnotation, setSelectedAnnotation] = useState<Annotation | null>(null); const [selectedAnnotation, setSelectedAnnotation] = useState<Annotation | null>(null);
const [isDirty, setIsDirty] = useState(false); const [isDirty, setIsDirty] = useState(false);
const [image, setImage] = useState<HTMLImageElement | null>(null); const [image, setImage] = useState<HTMLImageElement | null>(null);
@ -425,10 +425,11 @@ const ImageAnnotation: React.FC = () => {
try { try {
const handle = await saveFileWFS( const handle = await saveFileWFS(
currentFileResult.current?.handle, currentFileResult.current?.handle,
JSON.stringify(imageMetaData), toString(imageMetaData),
imageFileNameRef.current ? `${imageFileNameRef.current}.json` : 'metadata.json' imageFileNameRef.current ? `${imageFileNameRef.current}.json` : 'metadata.json'
); );
// 更新文件句柄 // 更新文件句柄
if (handle !== currentFileResult.current?.handle) { if (handle !== currentFileResult.current?.handle) {
currentFileResult.current = { currentFileResult.current = {
file: await handle.getFile(), file: await handle.getFile(),
@ -477,7 +478,7 @@ const ImageAnnotation: React.FC = () => {
if (definition) { if (definition) {
Annotations.update({ Annotations.update({
id, id,
tip: <Tip>{displayName} ({name})</Tip> _tip: <Tip>{displayName} ({name})</Tip>
}); });
} }
}; };