合并画布代码
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
//import { fabric } from "fabric-with-all";
|
||||
import { fabric } from "fabric-with-all";
|
||||
import initAligningGuidelines, {
|
||||
initCenteringGuidelines,
|
||||
} from "../utils/helperLine";
|
||||
@@ -14,10 +14,15 @@ import { createCanvas } from "../utils/canvasFactory";
|
||||
import { CanvasEventManager } from "./events/CanvasEventManager";
|
||||
import CanvasConfig from "../config/canvasConfig";
|
||||
import { RedGreenModeManager } from "./RedGreenModeManager";
|
||||
import { EraserStateManager } from "./EraserStateManager";
|
||||
import { deepClone, optimizeCanvasRendering } from "../utils/helper";
|
||||
import { ChangeFixedImageCommand } from "../commands/ObjectLayerCommands";
|
||||
import { isFunction } from "lodash-es";
|
||||
import {
|
||||
ChangeFixedImageCommand,
|
||||
AddImageToLayerCommand,
|
||||
} from "../commands/ObjectLayerCommands";
|
||||
restoreObjectLayerAssociations,
|
||||
simplifyLayers,
|
||||
validateLayerAssociations,
|
||||
} from "../utils/layerUtils";
|
||||
|
||||
export class CanvasManager {
|
||||
constructor(canvasElement, options) {
|
||||
@@ -34,6 +39,7 @@ export class CanvasManager {
|
||||
this.canvasHeight = options.canvasHeight || this.height; // 画布高度
|
||||
this.canvasColor = options.canvasColor || "#ffffff"; // 画布背景颜色
|
||||
this.enabledRedGreenMode = options.enabledRedGreenMode || false; // 是否启用红绿图模式
|
||||
this.eraserStateManager = null; // 橡皮擦状态管理器引用
|
||||
// 初始化画布
|
||||
this.initializeCanvas();
|
||||
}
|
||||
@@ -65,14 +71,6 @@ export class CanvasManager {
|
||||
layers: this.layers,
|
||||
});
|
||||
|
||||
// 初始化红绿图模式管理器
|
||||
this.redGreenModeManager = new RedGreenModeManager({
|
||||
canvas: this.canvas,
|
||||
layerManager: null, // 稍后设置
|
||||
toolManager: null, // 稍后设置
|
||||
commandManager: null, // 稍后设置
|
||||
});
|
||||
|
||||
// 设置画布辅助线
|
||||
initAligningGuidelines(this.canvas);
|
||||
|
||||
@@ -90,7 +88,7 @@ export class CanvasManager {
|
||||
*/
|
||||
_initCanvasEvents() {
|
||||
// 添加笔刷图像转换处理回调
|
||||
this.canvas.onBrushImageConverted = (fabricImage) => {
|
||||
this.canvas.onBrushImageConverted = async (fabricImage) => {
|
||||
// 如果图层管理器存在,将图像合并到当前活动图层
|
||||
if (this.layerManager) {
|
||||
// 获取当前活动图层
|
||||
@@ -107,21 +105,49 @@ export class CanvasManager {
|
||||
});
|
||||
|
||||
// 执行高保真合并操作
|
||||
this.eventManager?.mergeLayerObjectsForPerformance?.({
|
||||
await this.eventManager?.mergeLayerObjectsForPerformance?.({
|
||||
fabricImage,
|
||||
activeLayer,
|
||||
});
|
||||
|
||||
// 返回false表示不要自动添加到画布,因为我们已经通过图层管理器处理了
|
||||
return false;
|
||||
// 返回true表示不要自动添加到画布,因为我们已经通过图层管理器处理了
|
||||
return true;
|
||||
} else {
|
||||
console.warn("没有活动图层,使用默认行为添加图像");
|
||||
}
|
||||
}
|
||||
|
||||
// 返回true表示使用默认行为(直接添加到画布)
|
||||
return true;
|
||||
// 返回false表示使用默认行为(直接添加到画布)
|
||||
return false;
|
||||
};
|
||||
|
||||
this.eraserStateManager = new EraserStateManager(
|
||||
this.canvas,
|
||||
this.layerManager
|
||||
);
|
||||
|
||||
// 监听擦除开始事件
|
||||
this.canvas.on("erasing:start", () => {
|
||||
console.log("开始擦除");
|
||||
this.eraserStateManager.startErasing();
|
||||
});
|
||||
|
||||
// 监听擦除结束事件
|
||||
this.canvas.on("erasing:end", async (e) => {
|
||||
console.log("擦除完成", e.targets);
|
||||
// 可以在这里保存状态到命令管理器
|
||||
const affectedObjects = e.targets || [];
|
||||
const command = this.eraserStateManager.endErasing(affectedObjects);
|
||||
if (command && this.commandManager) {
|
||||
await this.commandManager?.executeCommand?.(command);
|
||||
} else {
|
||||
await command?.execute?.(); // 如果没有命令管理器,直接执行命令
|
||||
}
|
||||
|
||||
// 更新交互性
|
||||
command &&
|
||||
(await this.layerManager?.updateLayersObjectsInteractivity?.());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,6 +194,10 @@ export class CanvasManager {
|
||||
if (this.redGreenModeManager) {
|
||||
this.redGreenModeManager.layerManager = this.layerManager;
|
||||
}
|
||||
|
||||
if (this.eraserStateManager) {
|
||||
this.eraserStateManager.setLayerManager(this.layerManager);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,7 +350,8 @@ export class CanvasManager {
|
||||
|
||||
/**
|
||||
* 居中所有画布元素
|
||||
* 计算所有对象的边界框,然后将它们整体居中显示
|
||||
* 以背景层为参照,计算背景层的偏移量并应用到所有对象上
|
||||
* 这样可以保持对象间的相对位置关系不变
|
||||
*/
|
||||
centerAllObjects() {
|
||||
if (!this.canvas) return;
|
||||
@@ -333,45 +364,56 @@ export class CanvasManager {
|
||||
(obj) => obj.visible !== false && !obj.excludeFromExport
|
||||
);
|
||||
|
||||
// 如果只有背景层或没有可见对象,只居中背景层
|
||||
if (
|
||||
visibleObjects.length === 0 ||
|
||||
(visibleObjects.length === 1 && visibleObjects[0].isBackground)
|
||||
) {
|
||||
// 尝试居中背景层
|
||||
this.centerBackgroundLayer(this.width, this.height);
|
||||
return;
|
||||
}
|
||||
// 如果没有可见对象,直接返回
|
||||
if (visibleObjects.length === 0) return;
|
||||
|
||||
// 单独处理背景层
|
||||
// 获取背景对象
|
||||
const backgroundObject = visibleObjects.find((obj) => obj.isBackground);
|
||||
const contentObjects = backgroundObject
|
||||
? visibleObjects.filter((obj) => obj !== backgroundObject)
|
||||
: visibleObjects;
|
||||
|
||||
// 如果只有背景层,居中背景层
|
||||
if (contentObjects.length === 0 && backgroundObject) {
|
||||
this.centerBackgroundLayer(this.width, this.height);
|
||||
// 如果只有背景层或没有背景层,使用原有逻辑
|
||||
if (!backgroundObject) {
|
||||
console.warn("未找到背景层,使用默认居中逻辑");
|
||||
// 如果只有一个对象且可能是背景,直接居中
|
||||
if (visibleObjects.length === 1) {
|
||||
const obj = visibleObjects[0];
|
||||
obj.set({
|
||||
left: this.width / 2,
|
||||
top: this.height / 2,
|
||||
originX: "center",
|
||||
originY: "center",
|
||||
});
|
||||
obj.setCoords();
|
||||
this.canvas.renderAll();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算内容对象的边界
|
||||
const bounds = this._calculateObjectsBounds(contentObjects);
|
||||
|
||||
// 计算所有对象的中心点
|
||||
const objectsCenterX = bounds.left + bounds.width / 2;
|
||||
const objectsCenterY = bounds.top + bounds.height / 2;
|
||||
// 记录背景层居中前的位置
|
||||
const backgroundOldLeft = backgroundObject.left;
|
||||
const backgroundOldTop = backgroundObject.top;
|
||||
|
||||
// 计算画布中心点
|
||||
const canvasCenterX = this.width / 2;
|
||||
const canvasCenterY = this.height / 2;
|
||||
|
||||
// 计算需要移动的距离
|
||||
const deltaX = canvasCenterX - objectsCenterX;
|
||||
const deltaY = canvasCenterY - objectsCenterY;
|
||||
// 设置背景层居中
|
||||
backgroundObject.set({
|
||||
left: canvasCenterX,
|
||||
top: canvasCenterY,
|
||||
originX: "center",
|
||||
originY: "center",
|
||||
});
|
||||
|
||||
// 移动所有对象,包括背景层
|
||||
visibleObjects.forEach((obj) => {
|
||||
// 计算背景层的偏移量
|
||||
const deltaX = backgroundObject.left - backgroundOldLeft;
|
||||
const deltaY = backgroundObject.top - backgroundOldTop;
|
||||
|
||||
// 将相同的偏移量应用到所有其他对象上
|
||||
const otherObjects = visibleObjects.filter(
|
||||
(obj) => obj !== backgroundObject
|
||||
);
|
||||
|
||||
otherObjects.forEach((obj) => {
|
||||
obj.set({
|
||||
left: obj.left + deltaX,
|
||||
top: obj.top + deltaY,
|
||||
@@ -456,6 +498,7 @@ export class CanvasManager {
|
||||
// 如果需要裁剪背景层以外的内容,则更新蒙层位置
|
||||
// 创建或更新蒙层
|
||||
CanvasConfig.isCropBackground &&
|
||||
!this.enabledRedGreenMode &&
|
||||
this.createOrUpdateMask(backgroundLayerObject);
|
||||
return true;
|
||||
}
|
||||
@@ -480,12 +523,13 @@ export class CanvasManager {
|
||||
|
||||
// 创建蒙层 - 使用透明矩形作为裁剪区域
|
||||
this.maskLayer = new fabric.Rect({
|
||||
id: "canvasMaskLayer",
|
||||
width: bgWidth,
|
||||
height: bgHeight,
|
||||
left: left,
|
||||
top: top,
|
||||
fill: "transparent",
|
||||
stroke: "#cccccc",
|
||||
stroke: "transparent",
|
||||
strokeWidth: 1,
|
||||
strokeDashArray: [5, 5],
|
||||
selectable: false,
|
||||
@@ -504,20 +548,12 @@ export class CanvasManager {
|
||||
this.canvas.clipPath = new fabric.Rect({
|
||||
width: bgWidth,
|
||||
height: bgHeight,
|
||||
left: 0,
|
||||
top: 0,
|
||||
left: left,
|
||||
top: top,
|
||||
originX: backgroundLayerObject.originX || "left",
|
||||
originY: backgroundLayerObject.originY || "top",
|
||||
absolutePositioned: true,
|
||||
});
|
||||
|
||||
// 设置蒙层位置
|
||||
this.canvas.clipPath.set({
|
||||
left: left,
|
||||
top: top,
|
||||
});
|
||||
|
||||
this.canvas.renderAll();
|
||||
}
|
||||
getBackgroundLayer() {
|
||||
if (!this.canvas) return null;
|
||||
@@ -655,6 +691,39 @@ export class CanvasManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 更改固定图层的图片
|
||||
* @param {String} imageUrl 新的图片URL
|
||||
* @param {Object} options 选项
|
||||
* @param {String} options.targetLayerType 目标图层类型(background/fixed)
|
||||
* @param {Boolean} options.undoable 是否可撤销,默认不可撤销
|
||||
* @return {Object} 执行结果
|
||||
* */
|
||||
async changeFixedImage(imageUrl, options = {}) {
|
||||
if (!this.layerManager) {
|
||||
console.error("图层管理器未设置,无法更改固定图层图片");
|
||||
return;
|
||||
}
|
||||
const command = new ChangeFixedImageCommand({
|
||||
canvas: this.canvas,
|
||||
layerManager: this.layerManager,
|
||||
imageUrl: imageUrl,
|
||||
targetLayerType: options.targetLayerType || "fixed", // background/fixed
|
||||
});
|
||||
|
||||
command.undoable =
|
||||
options.undoable !== undefined ? options.undoable : false; // 默认不可撤销 undoable = true 为可撤销
|
||||
|
||||
return (
|
||||
(await command?.execute?.()) || {
|
||||
success: false,
|
||||
layerId: null,
|
||||
imageUrl: null,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出图片
|
||||
* @param {Object} options 导出选项
|
||||
@@ -663,6 +732,7 @@ export class CanvasManager {
|
||||
* @param {String} options.layerId 导出具体图层ID
|
||||
* @param {Array} options.layerIdArray 导出多个图层ID数组
|
||||
* @param {String} options.expPicType 导出图片类型 (png/jpg/svg)
|
||||
* @param {Boolean} options.restoreOpacityInRedGreen 红绿图模式下是否恢复透明度为1
|
||||
* @returns {String} 导出的图片数据URL
|
||||
*/
|
||||
exportImage(options = {}) {
|
||||
@@ -672,7 +742,39 @@ export class CanvasManager {
|
||||
}
|
||||
|
||||
try {
|
||||
return this.exportManager.exportImage(options);
|
||||
// 自动设置红绿图模式相关参数
|
||||
const enhancedOptions = {
|
||||
...options,
|
||||
// 如果没有明确指定,则根据当前模式自动设置
|
||||
restoreOpacityInRedGreen:
|
||||
options.restoreOpacityInRedGreen !== undefined
|
||||
? options.restoreOpacityInRedGreen
|
||||
: true, // 默认在红绿图模式下恢复透明度
|
||||
};
|
||||
|
||||
// 如果在红绿图模式下且没有指定具体的图层,自动包含所有普通图层
|
||||
if (
|
||||
this.enabledRedGreenMode &&
|
||||
!options.layerId &&
|
||||
(!options.layerIdArray || options.layerIdArray.length === 0)
|
||||
) {
|
||||
console.log("检测到红绿图模式,自动包含所有普通图层进行导出");
|
||||
|
||||
// 获取所有非背景、非固定的普通图层ID
|
||||
const normalLayerIds =
|
||||
this.layers?.value
|
||||
?.filter(
|
||||
(layer) => !layer.isBackground && !layer.isFixed && layer.visible
|
||||
)
|
||||
?.map((layer) => layer.id) || [];
|
||||
|
||||
if (normalLayerIds.length > 0) {
|
||||
enhancedOptions.layerIdArray = normalLayerIds;
|
||||
console.log("红绿图模式导出图层:", normalLayerIds);
|
||||
}
|
||||
}
|
||||
|
||||
return this.exportManager.exportImage(enhancedOptions);
|
||||
} catch (error) {
|
||||
console.error("CanvasManager导出图片失败:", error);
|
||||
throw error;
|
||||
@@ -709,129 +811,129 @@ export class CanvasManager {
|
||||
}
|
||||
|
||||
getJSON() {
|
||||
// 简化图层数据,在loadJSON时要根据id恢复引用
|
||||
let tempLayers = this.layers ? this.layers.value : [];
|
||||
// // 简化图层数据,在loadJSON时要根据id恢复引用
|
||||
// let tempLayers = this.layers ? this.layers.value : [];
|
||||
// // 创建对象ID映射表,用于快速查找
|
||||
// tempLayers = tempLayers.map((layer) => {
|
||||
// const newLayer = { ...layer };
|
||||
|
||||
// 为所有fabric对象生成ID(如果没有的话)
|
||||
const canvasObjects = this.canvas.getObjects();
|
||||
canvasObjects.forEach((obj) => {
|
||||
if (!obj.id) {
|
||||
obj.id = `obj_${Date.now()}_${Math.floor(Math.random() * 10000)}`;
|
||||
}
|
||||
});
|
||||
// // 处理fabricObjects数组
|
||||
// if (Array.isArray(layer.fabricObjects)) {
|
||||
// newLayer.fabricObjects = layer.fabricObjects
|
||||
// .map((item) => {
|
||||
// if (!item) return null;
|
||||
|
||||
// 创建对象ID映射表,用于快速查找
|
||||
const objectIdMap = new Map();
|
||||
canvasObjects.forEach((obj) => {
|
||||
if (obj.id) {
|
||||
objectIdMap.set(obj, obj.id);
|
||||
}
|
||||
});
|
||||
// // 确保对象有ID
|
||||
// if (!item.id) {
|
||||
// item.id = `obj_${Date.now()}_${Math.floor(
|
||||
// Math.random() * 10000
|
||||
// )}`;
|
||||
// }
|
||||
|
||||
tempLayers = tempLayers.map((layer) => {
|
||||
const newLayer = { ...layer };
|
||||
// return {
|
||||
// id: item.id,
|
||||
// type: item.type || "object", // 保存类型信息用于调试
|
||||
// };
|
||||
// })
|
||||
// .filter((item) => item !== null);
|
||||
// } else {
|
||||
// newLayer.fabricObjects = [];
|
||||
// }
|
||||
|
||||
// 处理fabricObjects数组
|
||||
if (Array.isArray(layer.fabricObjects)) {
|
||||
newLayer.fabricObjects = layer.fabricObjects
|
||||
.map((item) => {
|
||||
if (!item) return null;
|
||||
// if (layer.clippingMask) {
|
||||
// layer.clippingMask = {
|
||||
// id: layer.clippingMask.id,
|
||||
// };
|
||||
// }
|
||||
|
||||
// 确保对象有ID
|
||||
if (!item.id) {
|
||||
item.id = `obj_${Date.now()}_${Math.floor(
|
||||
Math.random() * 10000
|
||||
)}`;
|
||||
}
|
||||
// // 处理单个fabricObject
|
||||
// if (layer.fabricObject) {
|
||||
// if (!layer.fabricObject.id) {
|
||||
// layer.fabricObject.id = `obj_${Date.now()}_${Math.floor(
|
||||
// Math.random() * 10000
|
||||
// )}`;
|
||||
// }
|
||||
// newLayer.fabricObject = {
|
||||
// id: layer.fabricObject.id,
|
||||
// type: layer.fabricObject.type || "object",
|
||||
// };
|
||||
// } else {
|
||||
// newLayer.fabricObject = null;
|
||||
// }
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
type: item.type || "object", // 保存类型信息用于调试
|
||||
};
|
||||
})
|
||||
.filter((item) => item !== null);
|
||||
} else {
|
||||
newLayer.fabricObjects = [];
|
||||
}
|
||||
// // 处理子图层
|
||||
// if (Array.isArray(layer.children)) {
|
||||
// newLayer.children = layer.children.map((cItem) => {
|
||||
// const newChild = { ...cItem };
|
||||
|
||||
// 处理单个fabricObject
|
||||
if (layer.fabricObject) {
|
||||
if (!layer.fabricObject.id) {
|
||||
layer.fabricObject.id = `obj_${Date.now()}_${Math.floor(
|
||||
Math.random() * 10000
|
||||
)}`;
|
||||
}
|
||||
newLayer.fabricObject = {
|
||||
id: layer.fabricObject.id,
|
||||
type: layer.fabricObject.type || "object",
|
||||
};
|
||||
} else {
|
||||
newLayer.fabricObject = null;
|
||||
}
|
||||
// // 处理子图层的fabricObjects
|
||||
// if (Array.isArray(cItem.fabricObjects)) {
|
||||
// newChild.fabricObjects = cItem.fabricObjects
|
||||
// .map((item) => {
|
||||
// if (!item) return null;
|
||||
|
||||
// 处理子图层
|
||||
if (Array.isArray(layer.children)) {
|
||||
newLayer.children = layer.children.map((cItem) => {
|
||||
const newChild = { ...cItem };
|
||||
// if (!item.id) {
|
||||
// item.id = `obj_${Date.now()}_${Math.floor(
|
||||
// Math.random() * 10000
|
||||
// )}`;
|
||||
// }
|
||||
|
||||
// 处理子图层的fabricObjects
|
||||
if (Array.isArray(cItem.fabricObjects)) {
|
||||
newChild.fabricObjects = cItem.fabricObjects
|
||||
.map((item) => {
|
||||
if (!item) return null;
|
||||
// return {
|
||||
// id: item.id,
|
||||
// type: item.type || "object",
|
||||
// };
|
||||
// })
|
||||
// .filter((item) => item !== null);
|
||||
// } else {
|
||||
// newChild.fabricObjects = [];
|
||||
// }
|
||||
|
||||
if (!item.id) {
|
||||
item.id = `obj_${Date.now()}_${Math.floor(
|
||||
Math.random() * 10000
|
||||
)}`;
|
||||
}
|
||||
// // 处理子图层的fabricObject
|
||||
// if (cItem.fabricObject) {
|
||||
// if (!cItem.fabricObject.id) {
|
||||
// cItem.fabricObject.id = `obj_${Date.now()}_${Math.floor(
|
||||
// Math.random() * 10000
|
||||
// )}`;
|
||||
// }
|
||||
// newChild.fabricObject = {
|
||||
// id: cItem.fabricObject.id,
|
||||
// type: cItem.fabricObject.type || "object",
|
||||
// };
|
||||
// } else {
|
||||
// newChild.fabricObject = null;
|
||||
// }
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
type: item.type || "object",
|
||||
};
|
||||
})
|
||||
.filter((item) => item !== null);
|
||||
} else {
|
||||
newChild.fabricObjects = [];
|
||||
}
|
||||
|
||||
// 处理子图层的fabricObject
|
||||
if (cItem.fabricObject) {
|
||||
if (!cItem.fabricObject.id) {
|
||||
cItem.fabricObject.id = `obj_${Date.now()}_${Math.floor(
|
||||
Math.random() * 10000
|
||||
)}`;
|
||||
}
|
||||
newChild.fabricObject = {
|
||||
id: cItem.fabricObject.id,
|
||||
type: cItem.fabricObject.type || "object",
|
||||
};
|
||||
} else {
|
||||
newChild.fabricObject = null;
|
||||
}
|
||||
|
||||
return newChild;
|
||||
});
|
||||
} else {
|
||||
newLayer.children = [];
|
||||
}
|
||||
|
||||
return newLayer;
|
||||
});
|
||||
// return newChild;
|
||||
// });
|
||||
// } else {
|
||||
// newLayer.children = [];
|
||||
// }
|
||||
|
||||
// return newLayer;
|
||||
// });
|
||||
try {
|
||||
console.log(
|
||||
"获取画布JSON数据...",
|
||||
simplifyLayers(JSON.parse(JSON.stringify(this.layers.value)))
|
||||
);
|
||||
return JSON.stringify({
|
||||
canvas: this.canvas.toJSON([
|
||||
"id",
|
||||
"type",
|
||||
"layerId",
|
||||
"layerName",
|
||||
"isBackground",
|
||||
"isLocked",
|
||||
"isVisible",
|
||||
"isFixed",
|
||||
"parentId",
|
||||
"excludeFromExport",
|
||||
"eraser",
|
||||
"eraserable",
|
||||
"erasable",
|
||||
]),
|
||||
layers: tempLayers,
|
||||
layers: JSON.stringify(
|
||||
simplifyLayers(JSON.parse(JSON.stringify(this.layers.value)))
|
||||
), // 简化图层数据
|
||||
version: "1.0", // 添加版本信息
|
||||
timestamp: new Date().toISOString(), // 添加时间戳
|
||||
canvasWidth: this.canvasWidth.value,
|
||||
@@ -845,7 +947,7 @@ export class CanvasManager {
|
||||
}
|
||||
}
|
||||
|
||||
loadJSON(json) {
|
||||
loadJSON(json, calllBack) {
|
||||
console.log("加载画布JSON数据:", json);
|
||||
|
||||
// 确保传入的json是字符串格式
|
||||
@@ -859,7 +961,7 @@ export class CanvasManager {
|
||||
const parsedJson = JSON.parse(json);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const tempLayers = parsedJson?.layers || [];
|
||||
const tempLayers = JSON.parse(parsedJson?.layers) || [];
|
||||
const canvasData = parsedJson?.canvas;
|
||||
|
||||
if (!tempLayers) {
|
||||
@@ -872,9 +974,11 @@ export class CanvasManager {
|
||||
return;
|
||||
}
|
||||
|
||||
this.canvasWidth.value = parsedJson.canvasWidth || this.width;
|
||||
this.canvasHeight.value = parsedJson.canvasHeight || this.height;
|
||||
this.canvasColor.value = parsedJson.canvasColor || this.backgroundColor;
|
||||
this.layers.value = tempLayers;
|
||||
|
||||
// this.canvasWidth.value = parsedJson.canvasWidth || this.width;
|
||||
// this.canvasHeight.value = parsedJson.canvasHeight || this.height;
|
||||
// this.canvasColor.value = parsedJson.canvasColor || this.backgroundColor;
|
||||
|
||||
console.log("是否检测到红绿图模式内容:", this.enabledRedGreenMode);
|
||||
|
||||
@@ -885,107 +989,57 @@ export class CanvasManager {
|
||||
this.canvas.clear();
|
||||
|
||||
// 加载画布数据
|
||||
this.canvas.loadFromJSON(canvasData, () => {
|
||||
this.backgroundColor = parsedJson.backgroundColor || "#ffffff";
|
||||
try {
|
||||
// 重置画布数据
|
||||
this.setCanvasSize(this.canvas.width, this.canvas.height);
|
||||
this.canvas.loadFromJSON(canvasData, async () => {
|
||||
await optimizeCanvasRendering(this.canvas, async () => {
|
||||
this.backgroundColor = parsedJson.backgroundColor || "#ffffff";
|
||||
try {
|
||||
// 重置画布数据
|
||||
this.setCanvasSize(this.canvas.width, this.canvas.height);
|
||||
|
||||
// 创建对象ID映射表,用于快速查找
|
||||
const objectIdMap = new Map();
|
||||
const canvasObjects = this.canvas.getObjects();
|
||||
// 重新构建对象关系
|
||||
restoreObjectLayerAssociations(
|
||||
this.layers.value,
|
||||
this.canvas.getObjects()
|
||||
);
|
||||
|
||||
canvasObjects.forEach((obj) => {
|
||||
if (obj.id) {
|
||||
objectIdMap.set(obj.id, obj);
|
||||
}
|
||||
});
|
||||
// 验证图层关联关系 - 稳定后可以注释
|
||||
const isValidate = validateLayerAssociations(
|
||||
this.layers.value,
|
||||
this.canvas.getObjects()
|
||||
);
|
||||
|
||||
// 辅助函数:根据ID查找对象
|
||||
const findObjectById = (id) => {
|
||||
if (!id) return null;
|
||||
return objectIdMap.get(id) || null;
|
||||
};
|
||||
console.log("图层关联验证结果:", isValidate);
|
||||
|
||||
// 恢复图层数据
|
||||
this.layers.value = tempLayers.map((layer) => {
|
||||
const restoredLayer = { ...layer };
|
||||
this.canvas.activeLayerId.value =
|
||||
parsedJson?.activeLayerId || this.layers.value[0]?.id || null;
|
||||
|
||||
// 恢复fabricObjects数组
|
||||
if (Array.isArray(layer.fabricObjects)) {
|
||||
restoredLayer.fabricObjects = layer.fabricObjects
|
||||
.map((item) => {
|
||||
if (!item || !item.id) return null;
|
||||
return findObjectById(item.id);
|
||||
})
|
||||
.filter((obj) => obj !== null);
|
||||
} else {
|
||||
restoredLayer.fabricObjects = [];
|
||||
}
|
||||
// // 如果检测到红绿图模式内容,进行缩放调整
|
||||
// if (this.enabledRedGreenMode) {
|
||||
// this._rescaleRedGreenModeContent();
|
||||
// }
|
||||
|
||||
// 恢复单个fabricObject
|
||||
if (layer.fabricObject && layer.fabricObject.id) {
|
||||
restoredLayer.fabricObject = findObjectById(
|
||||
layer.fabricObject.id
|
||||
);
|
||||
} else {
|
||||
restoredLayer.fabricObject = null;
|
||||
}
|
||||
// 重载代码后支持回调中操作一些内容
|
||||
await calllBack?.();
|
||||
|
||||
// 恢复子图层
|
||||
if (Array.isArray(layer.children)) {
|
||||
restoredLayer.children = layer.children.map((cItem) => {
|
||||
const restoredChild = { ...cItem };
|
||||
// 确保所有对象的交互性正确设置
|
||||
await this.layerManager?.updateLayersObjectsInteractivity?.(
|
||||
false
|
||||
);
|
||||
console.log(this.layerManager.layers.value);
|
||||
debugger;
|
||||
|
||||
// 恢复子图层的fabricObjects
|
||||
if (Array.isArray(cItem.fabricObjects)) {
|
||||
restoredChild.fabricObjects = cItem.fabricObjects
|
||||
.map((item) => {
|
||||
if (!item || !item.id) return null;
|
||||
return findObjectById(item.id);
|
||||
})
|
||||
.filter((obj) => obj !== null);
|
||||
} else {
|
||||
restoredChild.fabricObjects = [];
|
||||
}
|
||||
// 更新所有缩略图
|
||||
setTimeout(() => {
|
||||
this.updateAllThumbnails();
|
||||
}, 100);
|
||||
|
||||
// 恢复子图层的fabricObject
|
||||
if (cItem.fabricObject && cItem.fabricObject.id) {
|
||||
restoredChild.fabricObject = findObjectById(
|
||||
cItem.fabricObject.id
|
||||
);
|
||||
} else {
|
||||
restoredChild.fabricObject = null;
|
||||
}
|
||||
|
||||
return restoredChild;
|
||||
});
|
||||
} else {
|
||||
restoredLayer.children = [];
|
||||
}
|
||||
|
||||
return restoredLayer;
|
||||
});
|
||||
|
||||
this.canvas.activeLayerId.value =
|
||||
parsedJson?.activeLayerId || this.layers.value[0]?.id || null;
|
||||
|
||||
// 如果检测到红绿图模式内容,进行缩放调整
|
||||
if (this.enabledRedGreenMode) {
|
||||
this._rescaleRedGreenModeContent();
|
||||
console.log("画布JSON数据加载完成");
|
||||
resolve();
|
||||
} catch (error) {
|
||||
console.error("恢复图层数据失败:", error);
|
||||
reject(new Error("恢复图层数据失败: " + error.message));
|
||||
}
|
||||
|
||||
// 更新所有缩略图
|
||||
setTimeout(() => {
|
||||
this.updateAllThumbnails();
|
||||
}, 100);
|
||||
|
||||
console.log("画布JSON数据加载完成");
|
||||
resolve();
|
||||
} catch (error) {
|
||||
console.error("恢复图层数据失败:", error);
|
||||
reject(new Error("恢复图层数据失败: " + error.message));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user