合并画布代码
This commit is contained in:
204
src/component/Canvas/CanvasEditor/utils/layerUtils.js
Normal file
204
src/component/Canvas/CanvasEditor/utils/layerUtils.js
Normal file
@@ -0,0 +1,204 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user