import { AddLayerCommand, PasteLayerCommand, RemoveLayerCommand, MoveLayerCommand, ToggleLayerVisibilityCommand, RenameLayerCommand, LayerLockCommand, SetLayerOpacityCommand, SetLayerBlendModeCommand, MergeLayersCommand, GroupLayersCommand, UngroupLayersCommand, MergeLayerObjectsCommand, LayerObjectsToGroupCommand, ReorderLayersCommand, ReorderChildLayersCommand, } from "../commands/LayerCommands"; import { SetActiveLayerCommand, AddObjectToLayerCommand, RemoveObjectFromLayerCommand, } from "../commands/ObjectLayerCommands"; import { LayerType, BlendMode, createLayer, createBackgroundLayer, createFixedLayer, OperationType, OperationTypes, } from "../utils/layerHelper"; import { CreateBackgroundLayerCommand, UpdateBackgroundCommand, BackgroundSizeCommand, BackgroundSizeWithScaleCommand, } from "../commands/BackgroundCommands"; import CanvasConfig from "../config/canvasConfig"; /** * 图层管理器 - 负责管理画布上的所有图层 * 包含图层的创建、删除、修改、排序等操作 * 现在统一使用命令管理器进行状态管理 */ export class LayerManager { /** * 创建图层管理器 * @param {Object} options 配置选项 * @param {Object} options.canvas fabric.js画布实例 * @param {Object} options.layers 图层数组响应式引用 * @param {Object} options.activeLayerId 当前激活图层ID响应式引用 * @param {Object} options.commandManager 命令管理器 * @param {Object} options.canvasManager 画布管理器 * @param {String} options.editorMode 编辑器模式 * @param {Number} options.canvasWidth 画布宽度 * @param {Number} options.canvasHeight 画布高度 * @param {String} options.backgroundColor 背景颜色 */ constructor(options) { this.canvas = options.canvas; this.layers = options.layers; this.activeLayerId = options.activeLayerId; this.commandManager = options.commandManager; this.canvasManager = options.canvasManager || null; // 编辑器模式:draw(绘画)、select(选择)、pan(拖拽) this.editorMode = options.editorMode || CanvasConfig.defaultTool; // 画布尺寸 this.canvasWidth = options.canvasWidth || 800; this.canvasHeight = options.canvasHeight || 600; // 默认背景颜色 this.backgroundColor = options.backgroundColor || "#ffffff"; // 复制粘贴相关 this.clipboardData = null; // 操作状态标志,用于控制状态保存 this.isExecutingCommand = false; // 是否正在执行操作 this.operationInProgress = false; // 红绿图模式相关 this.isRedGreenMode = false; this.redGreenModeManager = null; // 初始化相关命令 this.initCommandManager(); } /** * 初始化命令管理器 * 现在直接使用命令类,不再需要注册命令 */ initCommandManager() { // 命令注册逻辑已移除,现在直接使用命令类实例化和执行 console.log("CommandManager 已初始化,使用直接命令调用模式"); } /** * 设置编辑器模式 * @param {string} mode 'draw'、'select'或'pan' */ toolChanged(mode) { if (!OperationTypes.includes(mode)) { console.warn(`不支持的编辑器模式: ${mode}`); return; } this.editorMode = mode; // 更新所有对象的交互性 this.updateLayersObjectsInteractivity(); console.log(`已切换到${mode}模式`); } setToolManager(toolManager) { this.toolManager = toolManager; } /** * 更新所有画布对象的交互性 * 根据当前编辑模式和图层状态设置对象的交互属性 * @private */ updateLayersObjectsInteractivity() { if (!this.canvas) return; // 性能优化:使用requestAnimationFrame requestAnimationFrame(() => { // 暂停渲染以提高性能 this.canvas.skipTargetFind = true; // this.canvas.discardActiveObject(); // 暂停实时渲染和对象查找 const wasRenderOnAddRemove = this.canvas.renderOnAddRemove; this.canvas.renderOnAddRemove = false; // 应用图层交互规则 this._applyInteractionRules(); // 恢复渲染设置 this.canvas.renderOnAddRemove = wasRenderOnAddRemove; this.canvas.skipTargetFind = false; // this.canvas.renderAll(); this.canvas.renderAll(); // 确保画布重新渲染 - 同步渲染 }); } // 私有方法:应用交互规则 _applyInteractionRules() { console.log("updateLayersObjectsInteractivity ===>", this.editorMode); const objects = this.canvas.getObjects(); const editorMode = this.editorMode || CanvasConfig.defaultTool; const layers = this.layers?.value || []; // 创建缓存以避免重复查找 const layerMap = {}; layers.forEach((layer) => { layerMap[layer.id] = layer; }); // 获取当前活动图层ID const currentActiveLayerId = this.activeLayerId?.value; // 批量更新对象 objects.forEach((obj) => { if (!obj.layerId) { // 没有关联图层的对象使用默认设置 obj.selectable = false; obj.evented = false; obj.erasable = false; // 未关联图层的对象不可擦除 return; } const layer = layerMap[obj.layerId]; if (!layer) return; // 设置可见性 obj.visible = layer.visible; // 判断对象是否在当前活动图层上 const isInActiveLayer = obj.layerId === currentActiveLayerId; // 基于 fabric-with-erasing 库的 erasable 属性设置擦除权限 // 只有活动图层、可见、非锁定、非背景、非固定图层的对象才可擦除 obj.erasable = isInActiveLayer && layer.visible && !layer.locked && !layer.isBackground && !layer.isFixed; // 图层状态决定交互性 if (layer.isBackground || obj.isBackground || layer.isFixed) { // 背景层永远不可选择和擦除 obj.selectable = false; obj.evented = false; obj.erasable = false; } else if (layer.locked) { // 锁定图层不可交互和擦除 obj.selectable = false; obj.evented = false; obj.erasable = false; } else { // 根据编辑模式设置交互性 switch (editorMode) { case OperationType.SELECT: obj.selectable = true; obj.evented = true; break; case OperationType.ERASER: // 橡皮擦模式:利用 fabric-with-erasing 的内置机制 // 只需要设置 erasable 属性,库会自动处理擦除逻辑 obj.selectable = false; obj.evented = true; // 需要设置为 true 以接收鼠标事件 // erasable 已在上面根据图层状态设置 break; case OperationType.DRAW: case OperationType.EYEDROPPER: case OperationType.PAN: case OperationType.WAVE: case OperationType.LIQUIFY: case OperationType.LASSO: case OperationType.LASSO_RECTANGLE: case OperationType.AREA_CUSTOM: case OperationType.AREA_RECTANGLE: obj.selectable = false; obj.evented = false; break; default: obj.selectable = false; obj.evented = false; } // 平移模式下,禁用多选和擦除 if (editorMode === OperationType.PAN) { obj.selectable = false; obj.evented = false; obj.erasable = false; } } // 应用图层视觉属性 if (layer.opacity !== undefined) obj.opacity = layer.opacity; if (layer.blendMode) obj.globalCompositeOperation = layer.blendMode; }); } /** * 创建新图层 * @param {string} name 图层名称 * @param {string} type 图层类型 * @param {Object} options 额外选项 * @returns {string} 新创建的图层ID */ createLayer(name = null, type = LayerType.EMPTY, options = {}) { // 生成唯一ID const layerId = `layer_${Date.now()}_${Math.floor(Math.random() * 1000)}`; const layerIndex = this.layers.value.length; // 计算插入位置,如果没有指定insertIndex,则根据当前选中图层决定插入位置 // 添加到图层列表 let insertIndex = this._getInsertIndexAboveActiveLayer(); if (options.insertIndex !== undefined) { insertIndex = options.insertIndex; } // 创建新图层 const newLayer = createLayer({ id: layerId, name: name || `图层 ${layerIndex + 1}`, type: type, visible: true, locked: false, opacity: 1.0, blendMode: BlendMode.NORMAL, fabricObjects: [], children: [], ...options, }); // 直接创建和执行命令 const command = new AddLayerCommand({ canvas: this.canvas, layers: this.layers, newLayer: newLayer, activeLayerId: this.activeLayerId, insertIndex: insertIndex, }); // 计算普通图层数量(非背景、非固定) const normalLayersCount = this.layers.value.filter( (layer) => !layer.isBackground && !layer.isFixed ).length; // 如果是第一个图层,或者普通图层数量小于等于3,设置为不可撤销 if (this.layers.value.length === 1 || normalLayersCount <= 3) { command.undoable = false; } // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } return layerId; } /** * 创建背景图层 * @param {string} name 图层名称 * @returns {string} 创建的背景层ID */ createBackgroundLayer(name = "背景") { // 检查是否已有背景图层 const hasBackgroundLayer = this.layers.value.some( (layer) => layer.isBackground ); if (hasBackgroundLayer) { console.warn("已存在背景层,不再创建新的背景层"); return null; } // 创建背景图层 const bgLayer = createBackgroundLayer({ name: name, canvasWidth: this.canvasWidth, canvasHeight: this.canvasHeight, backgroundColor: this.backgroundColor, }); // 直接创建和执行命令 const command = new CreateBackgroundLayerCommand({ canvas: this.canvas, layers: this.layers, activeLayerId: this.activeLayerId, canvasManager: this.canvasManager, backgroundLayer: bgLayer, }); // 背景图层设置为不可撤销 command.undoable = false; // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 返回创建的背景层ID return bgLayer.id; } /** * 创建固定图层 - 位于背景图层之上,普通图层之下 * @param {string} name 图层名称 * @returns {string} 创建的固定图层ID */ createFixedLayer(name = "固定图层") { // 检查是否已有固定图层 const hasFixedLayer = this.layers.value.some((layer) => layer.isFixed); if (hasFixedLayer) { console.warn("已存在固定图层,不再创建新的固定图层"); return null; } // 生成唯一ID const layerId = `fixed_layer_${Date.now()}_${Math.floor( Math.random() * 1000 )}`; // 创建固定图层 const fixedLayer = createFixedLayer({ id: layerId, name: name, }); // 直接创建和执行命令 const command = new AddLayerCommand({ canvas: this.canvas, layers: this.layers, newLayer: fixedLayer, activeLayerId: this.activeLayerId, insertIndex: this._getFixedLayerInsertionIndex(), }); // 固定图层设置为不可撤销 command.undoable = false; // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } return layerId; } /** * 获取应该插入固定图层的位置索引(在背景图层之上) * @private * @returns {Number} 插入索引 */ _getFixedLayerInsertionIndex() { // 找到背景图层的位置 const bgIndex = this.layers.value.findIndex((layer) => layer.isBackground); if (bgIndex !== -1) { return bgIndex; // 插入到背景图层之前(在数组中这意味着位于背景图层之上) } return this.layers.value.length; // 如果没有背景图层,则添加到最后 } /** * 创建普通图层 * @param {String} name 图层名称 (默认: null,将生成自动名称) * @param {String} type 图层类型 (默认: LayerType.EMPTY) * @param {Object} options 附加选项 * @returns {String} 新创建的图层ID */ createLayer(name = null, type = LayerType.EMPTY, options = {}) { // 生成唯一ID const layerId = `layer_${Date.now()}_${Math.floor(Math.random() * 1000)}`; const layerIndex = this.layers.value.length; // 计算插入位置,如果没有指定insertIndex,则根据当前选中图层决定插入位置 // 添加到图层列表 let insertIndex = this._getInsertIndexAboveActiveLayer(); if (options.insertIndex !== undefined) { insertIndex = options.insertIndex; } // 创建新图层 const newLayer = createLayer({ id: layerId, name: name || `图层 ${layerIndex + 1}`, type: type, visible: true, locked: false, opacity: 1.0, blendMode: BlendMode.NORMAL, fabricObjects: [], children: [], ...options, }); // 直接创建和执行命令 const command = new AddLayerCommand({ canvas: this.canvas, layers: this.layers, newLayer: newLayer, activeLayerId: this.activeLayerId, insertIndex: insertIndex, }); // 如果是第一个图层,设置为不可撤销 if (this.layers.value.length === 1) { command.undoable = false; } // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } return layerId; } /** * 创建背景图层 * @param {string} name 图层名称 * @returns {string} 创建的背景层ID */ createBackgroundLayer(name = "背景") { // 检查是否已有背景图层 const hasBackgroundLayer = this.layers.value.some( (layer) => layer.isBackground ); if (hasBackgroundLayer) { console.warn("已存在背景层,不再创建新的背景层"); return null; } // 创建背景图层 const bgLayer = createBackgroundLayer({ name: name, canvasWidth: this.canvasWidth, canvasHeight: this.canvasHeight, backgroundColor: this.backgroundColor, }); // 直接创建和执行命令 const command = new CreateBackgroundLayerCommand({ canvas: this.canvas, layers: this.layers, activeLayerId: this.activeLayerId, canvasManager: this.canvasManager, backgroundLayer: bgLayer, }); // 背景图层设置为不可撤销 command.undoable = false; // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 返回创建的背景层ID return bgLayer.id; } /** * 初始化图层,确保有背景层、固定图层和一个空白图层 */ initializeLayers() { // 如果没有任何图层,创建背景层、固定图层和一个空白图层 if (this.layers.value.length === 0) { // 创建背景图层 this.createBackgroundLayer(); // 创建固定图层,位于背景图层之上 this.createFixedLayer(); // 创建一个空白图层(默认位于背景图层和固定图层之上) this.createLayer("图层 1"); } else { // 检查是否已有背景层 const hasBackgroundLayer = this.layers.value.some( (layer) => layer.isBackground ); if (!hasBackgroundLayer) { this.createBackgroundLayer(); } // 检查是否已有固定图层 const hasFixedLayer = this.layers.value.some((layer) => layer.isFixed); if (!hasFixedLayer) { this.createFixedLayer(); } // 检查是否至少有一个普通图层(非背景、非固定) const hasNormalLayer = this.layers.value.some( (layer) => !layer.isBackground && !layer.isFixed ); if (!hasNormalLayer) { this.createLayer("图层 1"); } } // 排序图层 this.sortLayers(); // 更新对象交互性 this.updateLayersObjectsInteractivity(); } /** * 添加对象到图层 * @param {Object} fabricObject fabric对象 * @param {string} layerId 目标图层ID,如果不提供则使用当前活动图层 * @returns {Object} 添加的对象 */ addObjectToLayer(fabricObject, layerId = null) { const targetLayerId = layerId || this.activeLayerId.value; // 如果没有指定图层ID,也没有活动图层,则返回错误 if (!targetLayerId) { console.warn("没有指定目标图层ID且没有活动图层,无法添加对象"); return null; } // 验证目标图层是否存在 const targetLayer = this.getLayerById(targetLayerId); if (!targetLayer) { console.error(`目标图层 ${targetLayerId} 不存在`); return null; } // 直接创建和执行命令 const command = new AddObjectToLayerCommand({ canvas: this.canvas, layers: this.layers, layerId: targetLayerId, fabricObject: fabricObject, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } return fabricObject; } /** * 向固定图层添加对象 * @param {Object} fabricObject fabric对象 * @returns {Object|null} 添加的对象或null(如果添加失败) */ addObjectToFixedLayer(fabricObject) { // 查找固定图层 const fixedLayer = this.layers.value.find((layer) => layer.isFixed); // 如果没有固定图层,则创建一个 if (!fixedLayer) { const fixedLayerId = this.createFixedLayer(); return this.addObjectToLayer(fabricObject, fixedLayerId); } // 添加对象到固定图层 return this.addObjectToLayer(fabricObject, fixedLayer.id); } /** * 从图层中移除对象 * @param {string|Object} objectOrId 要移除的对象或其ID * @returns {boolean} 是否移除成功 */ removeObjectFromLayer(objectOrId) { // 获取对象ID const objectId = typeof objectOrId === "string" ? objectOrId : objectOrId.id; if (!objectId) { console.error("无效的对象ID"); return false; } // 直接创建和执行命令 const command = new RemoveObjectFromLayerCommand({ canvas: this.canvas, layers: this.layers, objectId: objectId, objectOrId: objectOrId, }); // 执行命令 if (this.commandManager) { return this.commandManager.execute(command); } else { return command.execute(); } } /** * 设置活动图层 * @param {string} layerId 图层ID */ setActiveLayer(layerId, options = {}) { // 直接创建和执行命令 const command = new SetActiveLayerCommand({ layers: this.layers, canvas: this.canvas, layerManager: this, activeLayerId: this.activeLayerId, layerId: layerId, editorMode: this.editorMode, ...options, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } } /** * 获取当前活动图层 * @return {Object} layer 图层对象 */ getActiveLayer() { // 查找当前活动图层 const activeLayer = this.layers.value.find( (layer) => layer.id === this.activeLayerId.value ); if (activeLayer) { return activeLayer; } else { console.warn("没有活动图层"); return null; } } // 获取当前活动图层ID getActiveLayerId() { return this.activeLayerId.value; } /** * 根据ID获取图层 * @param {string} layerId 图层ID * @returns {Object|null} 图层对象或null */ getLayerById(layerId) { if (!layerId || !this.layers.value) return null; return this.layers.value.find((layer) => layer.id === layerId) || null; } /** * 获取当前图层对象的列表 * @param {string} layerId 可选,指定图层ID,默认使用当前活动图层 * @returns {Array} 图层中的对象列表 */ getLayerObjects(layerId = null) { const targetLayerId = layerId || this.activeLayerId.value; if (!targetLayerId) return []; const layer = this.getLayerById(targetLayerId); if (!layer) return []; // 如果是背景图层且有单个对象 if (layer.isBackground && layer.fabricObject) { return [layer.fabricObject]; } // 普通图层返回对象列表 return Array.isArray(layer.fabricObjects) ? layer.fabricObjects : []; } /** * 移除图层 * @param {string} layerId 图层ID * @returns {boolean} 是否移除成功 */ removeLayer(layerId) { // 查找要删除的图层 const layer = this.layers.value.find((layer) => layer.id === layerId); // 如果是背景层或固定层,不允许删除 if (layer && (layer.isBackground || layer.isFixed)) { console.warn(layer.isBackground ? "背景层不可删除" : "固定层不可删除"); return false; } // 如果图层有子图层,提示确认 if (layer && layer.children && layer.children.length > 0) { console.warn("该图层包含子图层,删除将同时删除所有子图层"); } // 直接创建和执行命令 const command = new RemoveLayerCommand({ canvas: this.canvas, layers: this.layers, layerId: layerId, activeLayerId: this.activeLayerId, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } return true; } /** * 移动图层位置 * @param {string} layerId 图层ID * @param {string} direction 移动方向,'up'或'down' * @returns {boolean} 是否移动成功 */ moveLayer(layerId, direction) { // 查找要移动的图层 const layer = this.layers.value.find((layer) => layer.id === layerId); // 如果是背景层或固定层,不允许移动 if (layer && (layer.isBackground || layer.isFixed)) { console.warn(layer.isBackground ? "背景层不可移动" : "固定层不可移动"); return false; } // 直接创建和执行命令 const command = new MoveLayerCommand({ canvas: this.canvas, layers: this.layers, layerId: layerId, direction: direction, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新画布渲染顺序 this._rearrangeObjects(); return true; } /** * 切换图层可见性 * @param {string} layerId 图层ID * @returns {boolean} 更新后的可见性状态 */ toggleLayerVisibility(layerId) { // 直接创建和执行命令 const command = new ToggleLayerVisibilityCommand({ canvas: this.canvas, layers: this.layers, layerId: layerId, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新对象交互性 this.updateLayersObjectsInteractivity(); // 获取当前可见性 const layer = this.layers.value.find((layer) => layer.id === layerId); return layer ? layer.visible : false; } /** * 切换图层锁定状态 * @param {string} layerId 图层ID * @returns {boolean} 更新后的锁定状态 */ toggleLayerLock(layerId) { // 直接创建和执行命令 const command = new LayerLockCommand({ canvas: this.canvas, layers: this.layers, layerId: layerId, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新对象交互性 this.updateLayersObjectsInteractivity(); // 获取当前锁定状态 const layer = this.layers.value.find((layer) => layer.id === layerId); return layer ? layer.locked : false; } /** * 设置图层不透明度 * @param {string} layerId 图层ID * @param {number} opacity 不透明度值 (0-1) */ setLayerOpacity(layerId, opacity) { // 直接创建和执行命令 const command = new SetLayerOpacityCommand({ canvas: this.canvas, layers: this.layers, layerId: layerId, opacity: opacity, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新图层对象不透明度 const layer = this.layers.value.find((layer) => layer.id === layerId); if (layer && layer.fabricObjects) { layer.fabricObjects.forEach((obj) => { obj.opacity = opacity; }); this.canvas.renderAll(); } } /** * 设置图层混合模式 * @param {string} layerId 图层ID * @param {string} blendMode 混合模式 */ setLayerBlendMode(layerId, blendMode) { // 直接创建和执行命令 const command = new SetLayerBlendModeCommand({ canvas: this.canvas, layers: this.layers, layerId: layerId, blendMode: blendMode, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新图层对象混合模式 const layer = this.layers.value.find((layer) => layer.id === layerId); if (layer && layer.fabricObjects) { layer.fabricObjects.forEach((obj) => { obj.globalCompositeOperation = blendMode; }); this.canvas.renderAll(); } } /** * 重命名图层 * @param {string} layerId 图层ID * @param {string} newName 新名称 */ renameLayer(layerId, newName) { // 直接创建和执行命令 const command = new RenameLayerCommand({ canvas: this.canvas, layers: this.layers, layerId: layerId, newName: newName, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新图层对象上的图层名称 const layer = this.layers.value.find((layer) => layer.id === layerId); if (layer && layer.fabricObjects) { layer.fabricObjects.forEach((obj) => { obj.layerName = newName; }); } } /** * 合并多个图层 * @param {Array} layerIds 要合并的图层ID数组 * @param {string} newName 合并后的图层名称,可选 * @returns {string} 合并后的新图层ID */ mergeLayers(layerIds, newName = null) { // 检查参数 if (!layerIds || !Array.isArray(layerIds) || layerIds.length < 2) { console.error("合并图层至少需要两个图层ID"); return null; } // 直接创建和执行命令 const command = new MergeLayersCommand({ canvas: this.canvas, layers: this.layers, layerIds: layerIds, newName: newName, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } return command.newLayerId; } /** * 将多个图层组合为一个组 * @param {Array} layerIds 要组合的图层ID数组 * @param {string} groupName 组名称,可选 * @returns {string} 新组图层ID */ groupLayers(layerIds, groupName = null) { // 检查参数 if (!layerIds || !Array.isArray(layerIds) || layerIds.length < 2) { console.error("组合图层至少需要两个图层ID"); return null; } // 直接创建和执行命令 const command = new GroupLayersCommand({ canvas: this.canvas, layers: this.layers, layerIds: layerIds, groupName: groupName, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } return command.groupId; } /** * 解组一个组图层 * @param {string} groupId 要解组的组图层ID * @returns {Array} 解组后的图层ID数组 */ ungroupLayers(groupId) { // 查找组图层 const groupLayer = this.layers.value.find((l) => l.id === groupId); if ( !groupLayer || !groupLayer.children || groupLayer.children.length === 0 ) { console.error(`${groupId} 不是有效的组图层或不包含子图层`); return null; } // 直接创建和执行命令 const command = new UngroupLayersCommand({ canvas: this.canvas, layers: this.layers, groupId: groupId, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } return command.childLayerIds; } /** * 调整画布和背景图层尺寸 * @param {number} width 宽度 * @param {number} height 高度 */ resizeCanvas(width, height, options = {}) { // 直接创建和执行命令 const command = new BackgroundSizeCommand({ canvas: this.canvas, layers: this.layers, canvasManager: this.canvasManager, newWidth: width, newHeight: height, isRedGreenMode: this.isInRedGreenMode(), // 传递红绿图模式状态 }); command.undoable = !!options.undoable; // 设置为可撤销 // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新存储的尺寸 this.canvasWidth = width; this.canvasHeight = height; } /** * 调整背景大小并等比缩放所有其他元素 * @param {number} width 宽度 * @param {number} height 高度 */ resizeCanvasWithScale(width, height, options = {}) { // 检查是否有除背景层外的其他元素 const hasOtherElements = this.canvas .getObjects() .some((obj) => !obj.isBackground); if (hasOtherElements) { // 有其他元素时使用带缩放的命令 const command = new BackgroundSizeWithScaleCommand({ canvas: this.canvas, layers: this.layers, canvasManager: this.canvasManager, newWidth: width, newHeight: height, isRedGreenMode: this.isInRedGreenMode(), // 传递红绿图模式状态 }); command.undoable = !!options.undoable; // 设置为可撤销 // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } } else { // 没有其他元素时使用普通的背景尺寸调整命令 this.resizeCanvas(width, height, options); } // 更新存储的尺寸 this.canvasWidth = width; this.canvasHeight = height; } /** * 排序图层,确保图层顺序: 普通图层 > 固定图层 > 背景图层 */ sortLayers() { // 对图层进行排序:背景图层在最底层(数组最后),固定图层在中间 this.layers.value.sort((a, b) => { // 如果a是背景图层,它应该排在后面(最底层) if (a.isBackground) return 1; // 如果b是背景图层,它应该排在后面(最底层) if (b.isBackground) return -1; // 如果a是固定图层而b不是固定图层,a应该排在后面(固定图层在普通图层下方) if (a.isFixed && !b.isFixed) return 1; // 如果b是固定图层而a不是固定图层,b应该排在后面(固定图层在普通图层下方) if (b.isFixed && !a.isFixed) return -1; // 其他情况保持原有顺序 return 0; }); // 更新画布对象顺序 this._rearrangeObjects(); } /** * 重新排列画布上的对象以匹配图层顺序 * @private */ _rearrangeObjects() { if (!this.canvas) return; // 获取画布上的所有对象 const canvasObjects = [...this.canvas.getObjects()]; // 清空画布 this.canvas.clear(); // 按图层顺序(从底到顶)重新添加对象 // 注意:图层数组是从顶到底的顺序,需要反向遍历 for (let i = this.layers.value.length - 1; i >= 0; i--) { const layer = this.layers.value[i]; // 跳过不可见图层 if (!layer.visible) continue; if (layer.isBackground) { // 背景图层特殊处理 if (layer.fabricObject) { const bgObject = canvasObjects.find( (obj) => obj.id === layer.fabricObject.id ); if (bgObject) { this.canvas.add(bgObject); } else if (layer.fabricObject) { this.canvas.add(layer.fabricObject); } } } else if ( Array.isArray(layer.fabricObjects) && layer.fabricObjects.length > 0 ) { // 普通图层,添加所有fabricObjects layer.fabricObjects.forEach((obj) => { const originalObj = canvasObjects.find((o) => o.id === obj.id); if (originalObj) { this.canvas.add(originalObj); } else { this.canvas.add(obj); } }); } } // 更新对象交互性 this.updateLayersObjectsInteractivity(); // 渲染画布 this.canvas.renderAll(); } /** * 同步画布对象到图层数据 * 确保画布上的对象和图层数据一致 */ syncCanvasToLayers() { if (!this.canvas) return; // 获取画布上的所有对象 const canvasObjects = this.canvas.getObjects(); // 遍历所有图层 this.layers.value.forEach((layer) => { if (layer.isBackground) { // 背景图层处理 if (layer.fabricObject) { const existsOnCanvas = canvasObjects.some( (obj) => obj.id === layer.fabricObject.id ); if (!existsOnCanvas) { this.canvas.add(layer.fabricObject); } } } else if (Array.isArray(layer.fabricObjects)) { // 更新图层中的对象列表 const updatedObjects = []; // 处理已有对象 layer.fabricObjects.forEach((obj) => { const canvasObj = canvasObjects.find((cObj) => cObj.id === obj.id); if (canvasObj) { updatedObjects.push(canvasObj); } else { // 对象不在画布上,添加到画布 this.canvas.add(obj); updatedObjects.push(obj); } }); // 检查是否有新对象需要添加到图层 canvasObjects.forEach((canvasObj) => { if ( canvasObj.layerId === layer.id && !updatedObjects.some((obj) => obj.id === canvasObj.id) ) { updatedObjects.push(canvasObj); } }); // 更新图层的对象列表 layer.fabricObjects = updatedObjects; } }); // 重新排列对象以匹配图层顺序 this._rearrangeObjects(); } /** * 导出当前图层数据 * @returns {Object} 图层数据对象 */ exportLayersData() { // 深拷贝图层数据,避免修改原始数据 const layersData = JSON.parse(JSON.stringify(this.layers.value)); // 移除无法序列化的属性 layersData.forEach((layer) => { if (layer.fabricObjects) { // 序列化对象 layer.serializedObjects = layer.fabricObjects .map((obj) => { if (typeof obj.toObject === "function") { return obj.toObject(["id", "layerId", "layerName"]); } return null; }) .filter(Boolean); // 删除原始对象引用 delete layer.fabricObjects; } if (layer.fabricObject) { layer.serializedBackgroundObject = typeof layer.fabricObject.toObject === "function" ? layer.fabricObject.toObject(["id", "layerId", "layerName"]) : null; delete layer.fabricObject; } }); return { layers: layersData, activeLayerId: this.activeLayerId.value, canvasWidth: this.canvasWidth, canvasHeight: this.canvasHeight, backgroundColor: this.backgroundColor, editorMode: this.editorMode, }; } /** * 导入图层数据 * @param {Object} data 图层数据对象 * @returns {boolean} 是否导入成功 */ importLayersData(data) { if (!data || !data.layers || !Array.isArray(data.layers)) { console.error("无效的图层数据"); return false; } const fabric = window.fabric; if (!fabric) { console.error("未找到fabric库"); return false; } // 清除画布 this.canvas.clear(); // 清空图层列表 this.layers.value = []; // 设置画布尺寸 if (data.canvasWidth && data.canvasHeight) { this.canvasWidth = data.canvasWidth; this.canvasHeight = data.canvasHeight; this.canvas.setWidth(data.canvasWidth); this.canvas.setHeight(data.canvasHeight); } // 设置背景颜色 if (data.backgroundColor) { this.backgroundColor = data.backgroundColor; } // 设置编辑模式 if (data.editorMode) { this.editorMode = data.editorMode; } // 导入图层 const promises = data.layers.map((layerData) => { return new Promise((resolve) => { const newLayer = { ...layerData, fabricObjects: [], children: layerData.children || [], }; // 如果有序列化的对象,恢复它们 if ( layerData.serializedObjects && Array.isArray(layerData.serializedObjects) ) { fabric.util.enlivenObjects(layerData.serializedObjects, (objects) => { objects.forEach((obj) => { // 关联到图层 obj.layerId = newLayer.id; obj.layerName = newLayer.name; // 添加到画布 this.canvas.add(obj); // 添加到图层 newLayer.fabricObjects.push(obj); }); resolve(newLayer); }); } else if ( layerData.isBackground && layerData.serializedBackgroundObject ) { // 恢复背景对象 fabric.util.enlivenObjects( [layerData.serializedBackgroundObject], ([bgObject]) => { if (bgObject) { bgObject.layerId = newLayer.id; bgObject.layerName = newLayer.name; this.canvas.add(bgObject); newLayer.fabricObject = bgObject; } resolve(newLayer); } ); } else { resolve(newLayer); } }); }); // 等待所有图层加载完成 Promise.all(promises).then((layers) => { // 更新图层列表 this.layers.value = layers; // 设置活动图层 if (data.activeLayerId) { const activeLayer = layers.find( (layer) => layer.id === data.activeLayerId ); if (activeLayer && !activeLayer.isBackground && !activeLayer.locked) { this.activeLayerId.value = data.activeLayerId; } else { // 查找第一个非背景、非锁定的图层 const firstNormalLayer = layers.find( (layer) => !layer.isBackground && !layer.locked ); if (firstNormalLayer) { this.activeLayerId.value = firstNormalLayer.id; } } } // 确保至少有一个背景图层和一个普通图层 this.initializeLayers(); // 更新对象交互性 this.updateLayersObjectsInteractivity(); // 重新排列对象 this._rearrangeObjects(); }); return true; } /** * 复制图层数据到剪贴板 * @param {string} layerId 要复制的图层ID * @returns {Object} 复制的图层数据 */ copyLayer(layerId) { const layer = this.layers.value.find((l) => l.id === layerId); if (!layer) { console.error(`图层 ${layerId} 不存在`); return null; } // 不允许复制背景图层 if (layer.isBackground) { console.warn("不能复制背景图层"); return null; } // 序列化图层对象 const layerCopy = JSON.parse(JSON.stringify(layer)); // 序列化fabricObjects数组 if (layer.fabricObjects && layer.fabricObjects.length > 0) { layerCopy.serializedObjects = layer.fabricObjects .map((obj) => typeof obj.toObject === "function" ? obj.toObject(["id", "layerId", "layerName"]) : null ) .filter(Boolean); } // 存储到剪贴板 this.clipboardData = layerCopy; console.log(`已复制图层:${layer.name}`); return this.clipboardData; } /** * 剪切图层数据到剪贴板 * @param {string} layerId 要剪切的图层ID * @returns {Object} 剪切的图层数据 */ cutLayer(layerId) { const layer = this.layers.value.find((l) => l.id === layerId); if (!layer) { console.error(`图层 ${layerId} 不存在`); return null; } // 不允许剪切背景图层 if (layer.isBackground) { console.warn("不能剪切背景图层"); return null; } // 检查是否是唯一的普通图层 const normalLayers = this.layers.value.filter((l) => !l.isBackground); if (normalLayers.length === 1) { console.warn("不能剪切唯一的普通图层"); return null; } // 序列化图层对象 const layerCopy = JSON.parse(JSON.stringify(layer)); // 序列化fabricObjects数组 if (layer.fabricObjects && layer.fabricObjects.length > 0) { layerCopy.serializedObjects = layer.fabricObjects .map((obj) => typeof obj.toObject === "function" ? obj.toObject(["id", "layerId", "layerName"]) : null ) .filter(Boolean); } // 存储到剪贴板 this.clipboardData = layerCopy; // 记录是剪切操作,用于粘贴时的处理 this.clipboardData.isCut = true; // 从画布中移除图层中的所有对象 if (layer.fabricObjects && layer.fabricObjects.length > 0) { layer.fabricObjects.forEach((obj) => { this.canvas.remove(obj); }); } // 如果剪切的是当前活动图层,需要切换到其他图层 if (this.activeLayerId.value === layerId) { // 查找下一个可用的图层 const nextLayer = this._findNextAvailableLayer(layerId); if (nextLayer) { this.setActiveLayer(nextLayer.id); } } // 直接创建和执行命令 const command = new RemoveLayerCommand({ canvas: this.canvas, layers: this.layers, layerId: layerId, activeLayerId: this.activeLayerId, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新对象交互性 this.updateLayersObjectsInteractivity(); console.log(`已剪切图层:${layer.name}`); return this.clipboardData; } /** * 粘贴图层 * @returns {string} 新创建的图层ID */ /** * 粘贴图层 * @returns {string} 新创建的图层ID */ pasteLayer() { if (!this.clipboardData) { console.error("剪贴板中没有图层数据"); return null; } // 使用命令管理器执行粘贴命令 if (this.commandManager) { return this.commandManager.executeByName("PasteLayer", { canvas: this.canvas, layers: this.layers, activeLayerId: this.activeLayerId, clipboardData: this.clipboardData, layerManager: this, // 传递LayerManager实例 }); } else { // 创建粘贴图层命令 const command = new PasteLayerCommand({ canvas: this.canvas, layers: this.layers, activeLayerId: this.activeLayerId, clipboardData: this.clipboardData, layerManager: this, // 传递LayerManager实例 }); // 执行命令 return command.execute(); } } /** * 查找下一个可用的图层(非背景、非锁定) * @param {string} excludeLayerId 要排除的图层ID * @returns {Object|null} 下一个可用的图层 * @private */ _findNextAvailableLayer(excludeLayerId) { // 查找第一个非背景、非锁定的图层,排除指定的图层 return ( this.layers.value.find( (layer) => layer.id !== excludeLayerId && !layer.isBackground && !layer.locked ) || null ); } /** * 获取活动图层上方的插入索引 * @returns {number} 插入索引 * @private */ _getInsertIndexAboveActiveLayer() { if (!this.activeLayerId.value) return 0; const activeLayerIndex = this.layers.value.findIndex( (layer) => layer.id === this.activeLayerId.value ); return activeLayerIndex !== -1 ? activeLayerIndex : 0; } /** * 保存画布状态 * 现在统一通过命令管理器的智能状态保存 */ saveCanvasState() { if (this.commandManager) { // 使用智能状态保存,避免不必要的状态保存 this.commandManager.saveStateIfNeeded({ name: "图层状态更新", stateType: "full", }); } } /** * 执行带状态保存的操作 * 统一的状态管理入口 */ executeWithState(operation, name = "图层操作") { if (this.commandManager) { return this.commandManager.executeWithState(operation, { name, stateType: "full", }); } else { // 降级处理 return typeof operation === "function" ? operation() : operation; } } /** * 批量执行图层操作 */ batchExecute(operations, name = "批量图层操作") { if (this.commandManager) { return this.commandManager.batch(operations, name); } else { // 降级处理 const results = []; for (const operation of operations) { results.push(typeof operation === "function" ? operation() : operation); } return results; } } /** * 清理画布,移除所有图层 */ clearCanvas() { // 清空画布 this.canvas.clear(); // 清空图层列表 this.layers.value = []; // 重新初始化基本图层 this.initializeLayers(); console.log("已清空画布"); } /** * 合并图层内的对象为单一图像 * @param {string} layerId 图层ID,默认使用当前活动图层 * @param {fabric.Image} newImage 要合并的新图像(可选) * @returns {Promise} 合并后的图像ID */ async mergeLayerObjects(activeLayer, fabricImage = null) { if (!activeLayer) { console.error(`活动图层不存在`); return null; } // 直接创建和执行命令 const command = new MergeLayerObjectsCommand({ canvas: this.canvas, layers: this.layers, fabricImage, activeLayer, }); // 执行命令 return command; } /** * 合并图层内对象成组的命令 * 将新的图像与图层内现有对象合并为一个组对象 * 注意:此命令与 MergeLayerObjectsCommand 类似,但它创建一个组而不是单个图像对象 */ async LayerObjectsToGroup(activeLayer, fabricImage = null) { // 检查活动图层是否存在 if (!activeLayer) { console.error(`活动图层不存在`); return null; } // 直接创建和执行命令 const command = new LayerObjectsToGroupCommand({ canvas: this.canvas, layers: this.layers, fabricImage, activeLayer, }); // 执行命令 return command; } /** * 更新背景图层颜色 * @param {string} backgroundColor 背景颜色 */ updateBackgroundColor(backgroundColor) { // 查找背景图层 const backgroundLayer = this.layers.value.find( (layer) => layer.isBackground ); if (!backgroundLayer) { console.warn("没有找到背景图层"); return; } // 直接创建和执行命令 const command = new UpdateBackgroundCommand({ canvas: this.canvas, layers: this.layers, canvasManager: this.canvasManager, backgroundColor: backgroundColor, }); // 执行命令 if (this.commandManager) { this.commandManager.execute(command); } else { command.execute(); } // 更新存储的背景颜色 this.backgroundColor = backgroundColor; } /** * 获取图层缩略图 * @param {string} layerId 图层ID * @param {number} width 缩略图宽度 * @param {number} height 缩略图高度 * @returns {string} Base64编码的缩略图 */ getLayerThumbnail(layerId, width = 100, height = 100) { const layer = this.getLayerById(layerId); if (!layer) { console.error(`图层 ${layerId} 不存在`); return null; } // 创建临时画布 const tempCanvas = document.createElement("canvas"); tempCanvas.width = width; tempCanvas.height = height; const ctx = tempCanvas.getContext("2d"); // 设置背景色 ctx.fillStyle = "#ffffff"; ctx.fillRect(0, 0, width, height); try { if (layer.isBackground && layer.fabricObject) { // 背景图层 const bgObj = layer.fabricObject; if (bgObj.toCanvasElement) { const element = bgObj.toCanvasElement(); ctx.drawImage(element, 0, 0, width, height); } } else if (layer.fabricObjects && layer.fabricObjects.length > 0) { // 普通图层 layer.fabricObjects.forEach((obj) => { if (obj.toCanvasElement) { const element = obj.toCanvasElement(); const scaleX = width / this.canvasWidth; const scaleY = height / this.canvasHeight; ctx.save(); ctx.scale(scaleX, scaleY); ctx.drawImage(element, obj.left || 0, obj.top || 0); ctx.restore(); } }); } return tempCanvas.toDataURL(); } catch (error) { console.error("生成图层缩略图失败:", error); return null; } } /** * 检查图层是否为空 * @param {string} layerId 图层ID * @returns {boolean} 是否为空图层 */ isLayerEmpty(layerId) { const layer = this.getLayerById(layerId); if (!layer) return true; if (layer.isBackground) { return !layer.fabricObject; } return !layer.fabricObjects || layer.fabricObjects.length === 0; } /** * 获取图层统计信息 * @returns {Object} 图层统计信息 */ getLayerStats() { const stats = { totalLayers: this.layers.value.length, backgroundLayers: 0, normalLayers: 0, lockedLayers: 0, hiddenLayers: 0, emptyLayers: 0, totalObjects: 0, }; this.layers.value.forEach((layer) => { if (layer.isBackground) { stats.backgroundLayers++; if (layer.fabricObject) { stats.totalObjects++; } } else { stats.normalLayers++; if (layer.fabricObjects) { stats.totalObjects += layer.fabricObjects.length; } } if (layer.locked) stats.lockedLayers++; if (!layer.visible) stats.hiddenLayers++; if (this.isLayerEmpty(layer.id)) stats.emptyLayers++; }); return stats; } /** * 清理空图层 * @returns {Array} 被清理的图层ID数组 */ cleanupEmptyLayers() { const emptyLayerIds = []; // 找出所有空的非背景图层 this.layers.value.forEach((layer) => { if (!layer.isBackground && this.isLayerEmpty(layer.id)) { emptyLayerIds.push(layer.id); } }); // 删除空图层 emptyLayerIds.forEach((layerId) => { this.removeLayer(layerId); }); if (emptyLayerIds.length > 0) { console.log(`已清理 ${emptyLayerIds.length} 个空图层`); } return emptyLayerIds; } /** * 销毁图层管理器 * 清理所有引用和事件监听器 */ dispose() { // 清空画布 if (this.canvas) { this.canvas.clear(); } // 清空图层数据 if (this.layers && this.layers.value) { this.layers.value = []; } // 清空剪贴板 this.clipboardData = null; // 清除引用 this.canvas = null; this.layers = null; this.activeLayerId = null; this.commandManager = null; this.canvasManager = null; this.toolManager = null; console.log("LayerManager 已销毁"); } /** * 创建文本图层并添加文本对象 * @param {Object} textObject Fabric文本对象 * @param {Object} options 文本选项 * @returns {Object} 创建的文本对象 */ createTextLayerWithObject(textObject, options = {}) { if (!this.canvas || !textObject) return null; // 确保对象有ID textObject.id = textObject.id || `text_${Date.now()}_${Math.floor(Math.random() * 1000)}`; // 创建文本图层 const layerName = options.name || "文本图层"; const layerId = this.createLayer(layerName, LayerType.TEXT, { layerProperties: { text: options.text || textObject.text || "新文本", fontFamily: options.fontFamily || textObject.fontFamily || "Arial", fontSize: options.fontSize || textObject.fontSize || 24, fontWeight: options.fontWeight || textObject.fontWeight || "normal", fontStyle: options.fontStyle || textObject.fontStyle || "normal", textAlign: options.textAlign || textObject.textAlign || "left", underline: options.underline || textObject.underline || false, linethrough: options.linethrough || textObject.linethrough || false, overline: options.overline || textObject.overline || false, fill: options.fill || textObject.fill || "#000000", textBackgroundColor: options.textBackgroundColor || textObject.textBackgroundColor || "transparent", lineHeight: options.lineHeight || textObject.lineHeight || 1.16, charSpacing: options.charSpacing || textObject.charSpacing || 0, }, }); // 把对象添加到新图层 textObject.layerId = layerId; textObject.layerName = layerName; // 添加到画布,如果还未添加 const isOnCanvas = this.canvas .getObjects() .some((obj) => obj.id === textObject.id); if (!isOnCanvas) { this.canvas.add(textObject); } // 更新图层中的对象列表 const layer = this.getLayerById(layerId); if (layer) { layer.fabricObjects = layer.fabricObjects || []; layer.fabricObjects.push(textObject); } // 设置此图层为活动图层 this.setActiveLayer(layerId); // 更新交互性 this.updateLayersObjectsInteractivity(); return textObject; } /** * 根据fabric对象查找所属图层 * @param {Object} fabricObject fabric对象 * @returns {Object|null} 图层对象或null */ findLayerByObject(fabricObject) { if (!fabricObject || !fabricObject.id) { return null; } // 遍历所有图层查找包含该对象的图层 for (const layer of this.layers.value) { // 检查背景图层 if (layer.isBackground && layer.fabricObject) { if (layer.fabricObject.id === fabricObject.id) { return layer; } } // 检查普通图层 if (layer.fabricObjects && Array.isArray(layer.fabricObjects)) { const foundObject = layer.fabricObjects.find( (obj) => obj.id === fabricObject.id ); if (foundObject) { return layer; } } } return null; } /** * 拖拽排序图层 * @param {number} oldIndex 原索引 * @param {number} newIndex 新索引 * @param {string} layerId 图层ID * @returns {boolean} 是否排序成功 */ reorderLayers(oldIndex, newIndex, layerId) { // 检查索引有效性 if ( oldIndex < 0 || newIndex < 0 || oldIndex >= this.layers.value.length || newIndex >= this.layers.value.length ) { console.warn("图层排序索引无效"); return false; } // 检查是否是同一位置 if (oldIndex === newIndex) { return true; } // 获取要移动的图层 const layer = this.layers.value[oldIndex]; if (!layer || layer.id !== layerId) { console.warn("图层ID与索引不匹配"); return false; } // 检查是否是背景层或固定层(不允许排序) if (layer.isBackground || layer.isFixed) { console.warn("背景层和固定层不能参与排序"); return false; } // 检查目标位置是否合法(不能移到背景层或固定层的位置) const targetLayer = this.layers.value[newIndex]; if (targetLayer && (targetLayer.isBackground || targetLayer.isFixed)) { console.warn("不能移动到背景层或固定层的位置"); return false; } // 创建并执行拖拽排序命令 const command = new ReorderLayersCommand({ layers: this.layers, oldIndex: oldIndex, newIndex: newIndex, layerId: layerId, canvas: this.canvas, }); // 执行命令 if (this.commandManager) { return this.commandManager.execute(command); } else { return command.execute(); } } /** * 拖拽排序子图层 * @param {string} parentId 父图层ID * @param {number} oldIndex 原索引 * @param {number} newIndex 新索引 * @param {string} layerId 子图层ID * @returns {boolean} 是否排序成功 */ reorderChildLayers(parentId, oldIndex, newIndex, layerId) { // 检查父图层是否存在 const parentLayer = this.getLayerById(parentId); if (!parentLayer) { console.warn(`父图层 ${parentId} 不存在`); return false; } // 获取所有子图层 const childLayers = this.layers.value.filter( (layer) => layer.parentId === parentId ); // 检查索引有效性 if ( oldIndex < 0 || newIndex < 0 || oldIndex >= childLayers.length || newIndex >= childLayers.length ) { console.warn("子图层排序索引无效"); return false; } // 检查是否是同一位置 if (oldIndex === newIndex) { return true; } // 验证图层ID const layer = childLayers[oldIndex]; if (!layer || layer.id !== layerId) { console.warn("子图层ID与索引不匹配"); return false; } // 创建并执行子图层拖拽排序命令 const command = new ReorderChildLayersCommand({ layers: this.layers, parentId: parentId, oldIndex: oldIndex, newIndex: newIndex, layerId: layerId, canvas: this.canvas, }); // 执行命令 if (this.commandManager) { return this.commandManager.execute(command); } else { return command.execute(); } } // 设置红绿图模式管理器 setRedGreenModeManager(redGreenModeManager) { this.redGreenModeManager = redGreenModeManager; } // 启用红绿图模式 enableRedGreenMode() { this.isRedGreenMode = true; console.log("图层管理器:红绿图模式已启用"); } // 禁用红绿图模式 disableRedGreenMode() { this.isRedGreenMode = false; console.log("图层管理器:红绿图模式已禁用"); } // 检查是否为红绿图模式 isInRedGreenMode() { return this.isRedGreenMode; } // 检查背景图层是否需要跟随画布大小变化(红绿图模式下) shouldBackgroundFollowCanvasSize() { return this.isRedGreenMode; } // 在红绿图模式下创建图层 - 限制功能 createLayerInRedGreenMode() { console.warn("红绿图模式下不支持创建新图层"); return null; } // 在红绿图模式下移除图层 - 限制功能 removeLayerInRedGreenMode(layerId) { console.warn("红绿图模式下不支持删除图层"); return false; } }