import { Command } from "./Command"; /** * 对象变换命令 * 轻量级命令,只记录对象的变换属性变化(位置、缩放、旋转) * 不保存整个对象或画布状态,只关注变换属性 */ export class TransformCommand extends Command { constructor(options) { super({ name: options.name || "对象变换", description: options.description || "移动、缩放或旋转对象", saveState: false, // 自己管理状态,避免递归 }); this.canvas = options.canvas; this.objectId = options.objectId; this.initialState = options.initialState || null; this.finalState = options.finalState || null; this.objectType = options.objectType || "object"; } /** * 执行命令 * 如果是首次执行,记录初始和最终状态 * 如果是重做,应用最终状态 */ execute() { if (!this.finalState) { console.warn("没有最终状态可应用"); return false; } // 查找目标对象 const targetObject = this._findObject(this.objectId); if (!targetObject) { console.warn(`未找到ID为 ${this.objectId} 的对象`); return false; } // 应用最终变换状态 this._applyTransform(targetObject, this.finalState); // 触发画布更新 this.canvas.renderAll(); return true; } /** * 撤销命令 * 应用初始状态 */ undo() { if (!this.initialState) { console.warn("没有初始状态可恢复"); return false; } // 查找目标对象 const targetObject = this._findObject(this.objectId); if (!targetObject) { console.warn(`未找到ID为 ${this.objectId} 的对象`); return false; } // 应用初始变换状态 this._applyTransform(targetObject, this.initialState); // 触发画布更新 this.canvas.renderAll(); return true; } /** * 查找对象 * @private */ _findObject(objectId) { if (!this.canvas) return null; return this.canvas.getObjects().find((obj) => obj.id === objectId); } /** * 应用变换状态到对象 * @private */ _applyTransform(object, transformState) { if (!object || !transformState) return; // 应用变换属性,只设置真正变化的值 Object.entries(transformState).forEach(([key, value]) => { object.set(key, value); }); // 确保对象更新 object.setCoords(); } /** * 获取命令信息 */ getInfo() { return { name: this.name, description: this.description, objectId: this.objectId, objectType: this.objectType, changedProps: this.finalState ? Object.keys(this.finalState) : [], }; } /** * 捕获对象的变换状态 * @static */ static captureTransformState(object) { if (!object) return null; // 只捕获变换相关的属性 return { left: object.left, top: object.top, scaleX: object.scaleX, scaleY: object.scaleY, angle: object.angle, flipX: object.flipX, flipY: object.flipY, skewX: object.skewX, skewY: object.skewY, }; } }