import { ref, nextTick } from 'vue';
|
import { ElMessage } from 'element-plus';
|
|
/**
|
* Canvas管理器 - 解决初始化竞态条件
|
*/
|
export function useCanvasManager() {
|
// 初始化Promise,用于处理并发初始化请求
|
const initializePromise = ref(null);
|
|
// Canvas相关引用
|
const canvasRef = ref(null);
|
const imageRef = ref(null);
|
const imageContainerRef = ref(null);
|
|
// 标注绘制器实例
|
let annotationDrawer = null;
|
|
/**
|
* 设置标注绘制器
|
*/
|
const setAnnotationDrawer = (drawer) => {
|
annotationDrawer = drawer;
|
};
|
|
/**
|
* 初始化Canvas(带并发控制)
|
*/
|
const initializeCanvas = async (refs, settings) => {
|
// 如果正在初始化,返回现有的Promise
|
if (initializePromise.value) {
|
console.log('[CanvasManager] Canvas正在初始化,等待完成...');
|
return initializePromise.value;
|
}
|
|
// 创建新的初始化Promise
|
initializePromise.value = new Promise(async (resolve, reject) => {
|
try {
|
console.log('[CanvasManager] 开始初始化Canvas...');
|
|
// 验证必要的引用
|
const { canvas, image, container } = refs;
|
if (!canvas || !image || !container) {
|
throw new Error('Canvas初始化失败:缺少必要的DOM引用');
|
}
|
|
// 保存引用
|
canvasRef.value = canvas;
|
imageRef.value = image;
|
imageContainerRef.value = container;
|
|
// 确保DOM已更新
|
await nextTick();
|
|
// 初始化标注绘制器
|
if (!annotationDrawer) {
|
throw new Error('Canvas初始化失败:标注绘制器未设置');
|
}
|
|
annotationDrawer.initialize(canvas, image, container);
|
|
// 应用初始设置
|
if (settings) {
|
console.log('[CanvasManager] 应用初始设置:', settings);
|
|
// 批量应用设置,减少重绘次数
|
annotationDrawer.initializeSettings({
|
lineWidth: settings.lineWidth || 2,
|
mode: settings.mode || null, // 不设置默认模式,由页面初始化时设置
|
annotationList: settings.annotations || [],
|
highlightedIds: settings.highlightedIds || [],
|
currentCategory: settings.currentCategory || null
|
});
|
}
|
|
console.log('[CanvasManager] Canvas初始化成功');
|
resolve(true);
|
} catch (error) {
|
console.error('[CanvasManager] Canvas初始化失败:', error);
|
reject(error);
|
} finally {
|
// 清除Promise引用,允许下次初始化
|
setTimeout(() => {
|
initializePromise.value = null;
|
}, 100);
|
}
|
});
|
|
return initializePromise.value;
|
};
|
|
/**
|
* 销毁Canvas
|
*/
|
const destroyCanvas = () => {
|
if (annotationDrawer && typeof annotationDrawer.destroy === 'function') {
|
annotationDrawer.destroy();
|
}
|
|
canvasRef.value = null;
|
imageRef.value = null;
|
imageContainerRef.value = null;
|
initializePromise.value = null;
|
|
console.log('[CanvasManager] Canvas已销毁');
|
};
|
|
/**
|
* 清除Canvas内容
|
*/
|
const clearCanvas = () => {
|
if (annotationDrawer && typeof annotationDrawer.clearAllAnnotations === 'function') {
|
annotationDrawer.clearAllAnnotations();
|
}
|
};
|
|
/**
|
* 更新Canvas设置
|
*/
|
const updateCanvasSettings = (settings) => {
|
if (!annotationDrawer) {
|
console.warn('[CanvasManager] 无法更新设置:标注绘制器未初始化');
|
return;
|
}
|
|
// 分别更新各项设置,避免不必要的重绘
|
if (settings.lineWidth !== undefined) {
|
annotationDrawer.setLineWidth(settings.lineWidth);
|
}
|
|
if (settings.mode !== undefined) {
|
annotationDrawer.setAnnotationMode(settings.mode);
|
}
|
|
if (settings.highlightedIds !== undefined) {
|
annotationDrawer.setHighlightedAnnotations(settings.highlightedIds);
|
}
|
|
if (settings.currentCategory !== undefined) {
|
annotationDrawer.setCurrentCategory(settings.currentCategory);
|
}
|
};
|
|
/**
|
* 批量更新标注(差量更新)
|
*/
|
const updateAnnotations = (changes) => {
|
if (!annotationDrawer) {
|
console.warn('[CanvasManager] 无法更新标注:标注绘制器未初始化');
|
return;
|
}
|
|
console.log('[CanvasManager] 执行差量更新:', {
|
added: changes.added?.length || 0,
|
removed: changes.removed?.length || 0,
|
updated: changes.updated?.length || 0
|
});
|
|
// 添加新标注
|
changes.added?.forEach(annotation => {
|
annotationDrawer.addAnnotation(annotation);
|
});
|
|
// 删除标注
|
changes.removed?.forEach(annotationId => {
|
annotationDrawer.removeAnnotation(annotationId);
|
});
|
|
// 更新标注
|
changes.updated?.forEach(annotation => {
|
annotationDrawer.updateAnnotation(annotation);
|
});
|
};
|
|
/**
|
* 渲染所有标注(全量更新)
|
*/
|
const renderAllAnnotations = (annotations) => {
|
if (!annotationDrawer) {
|
console.warn('[CanvasManager] 无法渲染标注:标注绘制器未初始化');
|
return;
|
}
|
|
clearCanvas();
|
annotationDrawer.renderExistingAnnotations(annotations);
|
};
|
|
/**
|
* 更新覆盖层位置(缩放时调用)
|
*/
|
const updateOverlayPosition = () => {
|
if (annotationDrawer && typeof annotationDrawer.updateOverlayPosition === 'function') {
|
annotationDrawer.updateOverlayPosition();
|
}
|
};
|
|
/**
|
* 设置标注完成回调
|
*/
|
const setAnnotationCompleteCallback = (callback) => {
|
if (annotationDrawer) {
|
annotationDrawer.setOnAnnotationComplete(callback);
|
}
|
};
|
|
return {
|
// 引用
|
canvasRef,
|
imageRef,
|
imageContainerRef,
|
|
// 方法
|
setAnnotationDrawer,
|
initializeCanvas,
|
destroyCanvas,
|
clearCanvas,
|
updateCanvasSettings,
|
updateAnnotations,
|
renderAllAnnotations,
|
updateOverlayPosition,
|
setAnnotationCompleteCallback,
|
|
// 获取绘制器实例(调试用)
|
getDrawer: () => annotationDrawer
|
};
|
}
|