import { isArray } from "lodash-es"; /** * 图层关联工具类 * 提供图层与画布对象关联管理的通用方法 */ /** * 构建单个图层与画布对象的关联关系 * @param {Object} layer 图层对象 * @param {Array} canvasObjects 画布对象数组 */ export function buildLayerAssociations(layer, canvasObjects) { if (!layer || !canvasObjects || !isArray(canvasObjects)) return; // 处理单个fabricObject关联 if (layer.fabricObject) { // 如果图层已经有关联的fabricObject,确保它的layerId和layerName正确 layer.fabricObject = canvasObjects.find((obj) => obj.id === layer.fabricObject.id) || null; } if (layer.clippingMask) { // clippingMask 可能是一个fabricObject或组 layer.clippingMask = canvasObjects.find((obj) => obj.id === layer.clippingMask.id) || null; } // 处理多个fabricObjects关联 if (layer.fabricObjects && isArray(layer.fabricObjects)) { layer.fabricObjects = layer.fabricObjects .map((fabricObject) => { // 确保每个fabricObject的layerId和layerName正确 const obj = canvasObjects.find((obj) => obj.id === fabricObject.id); if (obj) { obj.layerId = layer.id; // 确保对象的layerId正确 obj.layerName = layer.name; // 确保对象的layerName正确 return obj; } return null; // 如果没有找到对象,返回null }) .filter((obj) => obj !== null); // 过滤掉null值 } } /** * 恢复对象与图层的关联关系 * @param {Object} layerManager 图层管理器实例 * @param {Array} canvasObjects 画布对象数组 */ export function restoreObjectLayerAssociations(layers, canvasObjects) { if (!layers || !canvasObjects || !isArray(canvasObjects)) return; layers.forEach((layer) => { buildLayerAssociations(layer, canvasObjects); // 处理子图层 if (layer?.children?.length) { restoreObjectLayerAssociations(layer.children, canvasObjects); } }); } /** * 为画布对象设置图层信息 * @param {Object} fabricObject 画布对象 * @param {Object} layer 图层对象 */ export function setObjectLayerInfo(fabricObject, layer) { if (!fabricObject || !layer) return; fabricObject.layerId = layer.id; fabricObject.layerName = layer.name; } /** * 清除画布对象的图层信息 * @param {Object} fabricObject 画布对象 */ export function clearObjectLayerInfo(fabricObject) { if (!fabricObject) return; delete fabricObject.layerId; delete fabricObject.layerName; } /** * 验证图层关联关系的完整性 * @param {Object} layerManager 图层管理器实例 * @param {fabric.Canvas} canvas 画布实例 * @returns {Object} 验证结果 { valid: boolean, issues: Array } */ export function validateLayerAssociations(layers, canvasObjects) { const issues = []; // 检查画布对象是否都有对应的图层 canvasObjects.forEach((obj) => { if (obj.layerId) { const layer = layers.find((l) => l.id === obj.layerId); if (!layer) { issues.push({ type: "orphaned_object", objectId: obj.id, layerId: obj.layerId, message: `对象 ${obj.id} 关联的图层 ${obj.layerId} 不存在`, }); } } else { issues.push({ type: "missing_layer_id", objectId: obj.id, message: `对象 ${obj.id} 缺少图层ID关联`, }); } }); // 检查图层是否都有对应的画布对象 layers.forEach((layer) => { if (layer.fabricObject && layer.fabricObject.id) { const obj = canvasObjects.find((o) => o.id === layer.fabricObject.id); if (!obj) { issues.push({ type: "missing_object", layerId: layer.id, objectId: layer.fabricObject.id, message: `图层 ${layer.id} 关联的对象 ${layer.fabricObject.id} 不存在于画布中`, }); } } if (layer.fabricObjects && isArray(layer.fabricObjects)) { layer.fabricObjects.forEach((fabricObj) => { if (fabricObj.id) { const obj = canvasObjects.find((o) => o.id === fabricObj.id); if (!obj) { issues.push({ type: "missing_object", layerId: layer.id, objectId: fabricObj.id, message: `图层 ${layer.id} 关联的对象 ${fabricObj.id} 不存在于画布中`, }); } } }); } }); return { valid: issues.length === 0, issues, }; } /** * 简化layers对象属性,只保留必要的属性 * @param {Array} layers 图层数组 simplifyLayers(JSON.parse(JSON.stringify(this.layers.value))) */ export function simplifyLayers(layers) { if (!layers || !isArray(layers)) { console.warn("simplifyLayers 请传入有效的图层数组:", layers); return []; } layers.forEach((layer) => { // 处理图层遮罩 // 如果clippingMask是一个fabricObject或组,确保它的id正确 // 因为是fabric对象,所以没办法直接获取id,只能通过序列化获取 if (layer.clippingMask) { layer.clippingMask = layer.clippingMask?.id || null; } // 处理单个fabricObject if (layer.fabricObject) { layer.fabricObject = layer.fabricObject?.id; } // 处理多个fabricObjects if (layer.fabricObjects && isArray(layer.fabricObjects)) { layer.fabricObjects = layer.fabricObjects .map((fabricObject) => { return fabricObject?.id || null; // 确保每个fabricObject都能转换为对象 }) .filter((obj) => obj !== null); } // 处理子图层 if (layer.children && isArray(layer.children)) { layer.children = simplifyLayers(layer.children); } // 只保留必要的属性 layer = { id: layer.id, name: layer.name, visible: layer.visible, locked: layer.locked, opacity: layer.opacity, clippingMask: layer.clippingMask || null, fabricObject: layer.fabricObject || null, fabricObjects: layer.fabricObjects || [], children: layer.children || [], isBackground: layer.isBackground || false, ifFixed: layer.ifFixed || false, }; }); return layers; }