import { Command, CompositeCommand } from "./Command.js"; //import { fabric } from "fabric-with-all"; import { createLayer, LayerType } from "../utils/layerHelper.js"; /** * 创建选区命令 */ export class CreateSelectionCommand extends Command { constructor(options = {}) { super({ name: options.name || "创建选区", description: "在画布上创建选区", saveState: false, }); this.canvas = options.canvas; this.selectionManager = options.selectionManager; this.selectionObject = options.selectionObject; this.selectionType = options.selectionType || "rectangle"; } async execute() { if (!this.canvas || !this.selectionManager || !this.selectionObject) { console.error("无法创建选区:参数无效"); return false; } // 将选择对象添加到选区管理器 this.selectionManager.setSelectionObject(this.selectionObject); return true; } async undo() { if (!this.selectionManager) return false; this.selectionManager.clearSelection(); return true; } } /** * 反转选区命令 */ export class InvertSelectionCommand extends Command { constructor(options = {}) { super({ name: "反转选区", description: "反转当前选区", saveState: false, }); this.canvas = options.canvas; this.selectionManager = options.selectionManager; this.originalSelection = options.selectionManager ? options.selectionManager.getSelectionPath() : null; } async execute() { if (!this.canvas || !this.selectionManager) { console.error("无法反转选区:参数无效"); return false; } // 保存原始选区 if (!this.originalSelection) { this.originalSelection = this.selectionManager.getSelectionPath(); } // 反转选区 const result = await this.selectionManager.invertSelection(); return result; } async undo() { if (!this.selectionManager || !this.originalSelection) return false; // 恢复原始选区 this.selectionManager.setSelectionFromPath(this.originalSelection); return true; } } /** * 添加到选区命令 */ export class AddToSelectionCommand extends Command { constructor(options = {}) { super({ name: "添加到选区", description: "将新的选区添加到现有选区", saveState: false, }); this.canvas = options.canvas; this.selectionManager = options.selectionManager; this.newSelection = options.newSelection; this.originalSelection = options.selectionManager ? options.selectionManager.getSelectionPath() : null; } async execute() { if (!this.canvas || !this.selectionManager || !this.newSelection) { console.error("无法添加到选区:参数无效"); return false; } // 保存原始选区 if (!this.originalSelection) { this.originalSelection = this.selectionManager.getSelectionPath(); } // 添加到选区 const result = await this.selectionManager.addToSelection( this.newSelection ); return result; } async undo() { if (!this.selectionManager || !this.originalSelection) return false; // 恢复原始选区 this.selectionManager.setSelectionFromPath(this.originalSelection); return true; } } /** * 从选区中移除命令 */ export class RemoveFromSelectionCommand extends Command { constructor(options = {}) { super({ name: "从选区中移除", description: "从现有选区中移除指定区域", saveState: false, }); this.canvas = options.canvas; this.selectionManager = options.selectionManager; this.removeSelection = options.removeSelection; this.originalSelection = options.selectionManager ? options.selectionManager.getSelectionPath() : null; } async execute() { if (!this.canvas || !this.selectionManager || !this.removeSelection) { console.error("无法从选区中移除:参数无效"); return false; } // 保存原始选区 if (!this.originalSelection) { this.originalSelection = this.selectionManager.getSelectionPath(); } // 从选区中移除 const result = await this.selectionManager.removeFromSelection( this.removeSelection ); return result; } async undo() { if (!this.selectionManager || !this.originalSelection) return false; // 恢复原始选区 this.selectionManager.setSelectionFromPath(this.originalSelection); return true; } } /** * 清除选区命令 */ export class ClearSelectionCommand extends Command { constructor(options = {}) { super({ name: "清除选区", description: "清除当前选区", saveState: false, }); this.selectionManager = options.selectionManager; this.originalSelection = options.selectionManager ? options.selectionManager.getSelectionPath() : null; } async execute() { if (!this.selectionManager) { console.error("无法清除选区:参数无效"); return false; } // 保存原始选区 if (!this.originalSelection) { this.originalSelection = this.selectionManager.getSelectionPath(); } // 清除选区 this.selectionManager.clearSelection(); return true; } async undo() { if (!this.selectionManager || !this.originalSelection) return false; // 恢复原始选区 this.selectionManager.setSelectionFromPath(this.originalSelection); return true; } } /** * 羽化选区命令 */ export class FeatherSelectionCommand extends Command { constructor(options = {}) { super({ name: "羽化选区", description: "对当前选区应用羽化效果", saveState: false, }); this.selectionManager = options.selectionManager; this.featherAmount = options.featherAmount || 5; this.originalSelection = options.selectionManager ? options.selectionManager.getSelectionPath() : null; this.originalFeatherAmount = options.selectionManager ? options.selectionManager.getFeatherAmount() : 0; } async execute() { if (!this.selectionManager) { console.error("无法羽化选区:参数无效"); return false; } // 保存原始选区和羽化值 if (!this.originalSelection) { this.originalSelection = this.selectionManager.getSelectionPath(); this.originalFeatherAmount = this.selectionManager.getFeatherAmount(); } // 应用羽化 const result = await this.selectionManager.featherSelection( this.featherAmount ); return result; } async undo() { if (!this.selectionManager || !this.originalSelection) return false; // 恢复原始选区和羽化值 this.selectionManager.setSelectionFromPath(this.originalSelection); this.selectionManager.setFeatherAmount(this.originalFeatherAmount); return true; } } /** * 填充选区命令 */ export class FillSelectionCommand extends Command { constructor(options = {}) { super({ name: "填充选区", description: "使用指定颜色填充当前选区", saveState: false, }); this.canvas = options.canvas; this.layerManager = options.layerManager; this.selectionManager = options.selectionManager; this.color = options.color || "#000000"; this.targetLayerId = options.targetLayerId; this.createdObjectIds = []; } async execute() { if (!this.canvas || !this.layerManager || !this.selectionManager) { console.error("无法填充选区:参数无效"); return false; } // 获取选区路径 const selectionPath = this.selectionManager.getSelectionObject(); if (!selectionPath) { console.error("无法填充选区:当前没有选区"); return false; } // 确定目标图层 const layerId = this.targetLayerId || this.layerManager.getActiveLayerId(); if (!layerId) { console.error("无法填充选区:没有活动图层"); return false; } // 创建填充对象 const fillObject = new fabric.Path(selectionPath.path, { fill: this.color, stroke: null, opacity: 1, id: `fill_${Date.now()}_${Math.floor(Math.random() * 1000)}`, layerId: layerId, selectable: false, }); // 应用羽化效果(如果有) const featherAmount = this.selectionManager.getFeatherAmount(); if (featherAmount > 0) { fillObject.shadow = new fabric.Shadow({ color: this.color, blur: featherAmount, offsetX: 0, offsetY: 0, }); } // 添加到图层 this.layerManager.addObjectToLayer(layerId, fillObject); this.createdObjectIds.push(fillObject.id); // 清空选区 this.selectionManager.clearSelection(); return true; } async undo() { if (!this.layerManager || this.createdObjectIds.length === 0) return false; // 移除创建的填充对象 for (const id of this.createdObjectIds) { const layerObj = this._findObjectInLayers(id); if (layerObj) { this.layerManager.removeObjectFromLayer(layerObj.layerId, id); } } return true; } _findObjectInLayers(objectId) { if (!this.layerManager) return null; const layers = this.layerManager.layers.value; for (const layer of layers) { if (layer.fabricObjects) { const obj = layer.fabricObjects.find((obj) => obj.id === objectId); if (obj) return { object: obj, layerId: layer.id }; } } return null; } } /** * 复制选区内容到新图层命令 */ export class CopySelectionToNewLayerCommand extends CompositeCommand { constructor(options = {}) { super([], { name: "复制选区到新图层", description: "将选区中的内容复制到新图层", }); this.canvas = options.canvas; this.layerManager = options.layerManager; this.selectionManager = options.selectionManager; this.sourceLayerId = options.sourceLayerId; this.newLayerName = options.newLayerName || "选区复制"; this.newLayerId = null; this.copiedObjectIds = []; } async execute() { if (!this.canvas || !this.layerManager || !this.selectionManager) { console.error("无法复制选区:参数无效"); return false; } try { // 获取选区 const selectionObject = this.selectionManager.getSelectionObject(); if (!selectionObject) { console.error("无法复制选区:当前没有选区"); return false; } // 确定源图层 const sourceId = this.sourceLayerId || this.layerManager.getActiveLayerId(); const sourceLayer = this.layerManager.getLayerById(sourceId); if (!sourceLayer || !sourceLayer.fabricObjects) { console.error("无法复制选区:源图层无效或为空"); return false; } // 创建新图层 this.newLayerId = await this.layerManager.createLayer( this.newLayerName, LayerType.EMPTY ); // 获取选区内的对象 const objectsToCopy = sourceLayer.fabricObjects.filter((obj) => { return this.selectionManager.isObjectInSelection(obj); }); if (objectsToCopy.length === 0) { console.warn("选区内没有对象可复制"); return true; // 仍然返回成功,因为已创建了新图层 } // 复制对象到新图层 for (const obj of objectsToCopy) { // 克隆对象 const clonedObj = await this._cloneObject(obj); // 设置新的ID和图层ID const newId = `copy_${Date.now()}_${Math.floor(Math.random() * 1000)}`; clonedObj.id = newId; clonedObj.layerId = this.newLayerId; // 添加到新图层 await this.layerManager.addObjectToLayer(this.newLayerId, clonedObj); this.copiedObjectIds.push(newId); } // 设置新图层为活动图层 this.layerManager.setActiveLayer(this.newLayerId); // 清空选区 this.selectionManager.clearSelection(); return { newLayerId: this.newLayerId, copiedCount: this.copiedObjectIds.length, }; } catch (error) { console.error("复制选区过程中出错:", error); // 如果已经创建了新图层,需要进行清理 if (this.newLayerId) { try { await this.layerManager.removeLayer(this.newLayerId); } catch (cleanupError) { console.warn("清理新图层失败:", cleanupError); } } throw error; } } async _cloneObject(obj) { return new Promise((resolve, reject) => { if (!obj) { reject(new Error("对象无效,无法克隆")); return; } try { obj.clone((cloned) => { resolve(cloned); }); } catch (error) { reject(error); } }); } } /** * 从选区中删除内容命令 */ export class ClearSelectionContentCommand extends Command { constructor(options = {}) { super({ name: "清除选区内容", description: "删除选区中的内容", saveState: false, }); this.canvas = options.canvas; this.layerManager = options.layerManager; this.selectionManager = options.selectionManager; this.targetLayerId = options.targetLayerId; this.removedObjects = []; } async execute() { if (!this.canvas || !this.layerManager || !this.selectionManager) { console.error("无法清除选区内容:参数无效"); return false; } // 获取选区 const selectionObject = this.selectionManager.getSelectionObject(); if (!selectionObject) { console.error("无法清除选区内容:当前没有选区"); return false; } // 确定目标图层 const layerId = this.targetLayerId || this.layerManager.getActiveLayerId(); const layer = this.layerManager.getLayerById(layerId); if (!layer || !layer.fabricObjects) { console.error("无法清除选区内容:目标图层无效或为空"); return false; } // 找到选区内的对象 const objectsToRemove = layer.fabricObjects.filter((obj) => { return this.selectionManager.isObjectInSelection(obj); }); if (objectsToRemove.length === 0) { console.warn("选区内没有对象需要清除"); return true; } // 备份被删除的对象 this.removedObjects = objectsToRemove.map((obj) => ({ object: this._cloneObjectSync(obj), layerId: layerId, })); // 从图层中移除对象 for (const obj of objectsToRemove) { this.layerManager.removeObjectFromLayer(layerId, obj.id); } return { removedCount: objectsToRemove.length }; } async undo() { if (!this.layerManager || this.removedObjects.length === 0) return false; // 恢复被删除的对象 for (const item of this.removedObjects) { if (item.object && item.layerId) { const clonedObj = await this._cloneObject(item.object); this.layerManager.addObjectToLayer(item.layerId, clonedObj); } } return true; } _cloneObjectSync(obj) { // 这是一个简单的深拷贝,不适用于所有场景 // 在实际应用中,应该使用fabric.js的clone方法 if (!obj) return null; return JSON.parse(JSON.stringify(obj)); } async _cloneObject(obj) { return new Promise((resolve, reject) => { if (!obj) { reject(new Error("对象无效,无法克隆")); return; } try { if (typeof obj.clone === "function") { obj.clone((cloned) => { resolve(cloned); }); } else { // 如果对象没有clone方法(可能是因为它已经是序列化后的对象) // 在实际代码中需要适当处理这种情况 resolve(Object.assign({}, obj)); } } catch (error) { reject(error); } }); } } // 导入套索抠图命令 export { LassoCutoutCommand } from "./LassoCutoutCommand.js";