Files
aida_front/src/component/Canvas/CanvasEditor/commands/EraserCommand.js
2025-07-14 01:00:23 +08:00

98 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { isArray } from "lodash-es";
import { optimizeCanvasRendering } from "../utils/helper";
import { restoreObjectLayerAssociations } from "../utils/layerUtils";
import { Command } from "./Command";
/**
* 橡皮擦操作命令
* 支持橡皮擦操作的撤销和重做
*/
export class EraserCommand extends Command {
/**
* 构造函数
* @param {Object} options 命令选项
* @param {Object} options.canvas Fabric画布实例
* @param {Object} options.layerManager 图层管理器
* @param {Object} options.beforeSnapshot 擦除前的状态快照
* @param {Object} options.afterSnapshot 擦除后的状态快照
* @param {Array} options.affectedObjects 擦除影响的对象列表(可选)
*/
constructor(options) {
super({
name: "橡皮擦操作",
description: `擦除`,
...options,
});
this.canvas = options.canvas;
this.layerManager = options.layerManager;
this.beforeSnapshot = options.beforeSnapshot;
this.afterSnapshot = options.afterSnapshot;
this.affectedObjects = options.affectedObjects || [];
this.fristLoad = true; // 是否是第一次加载
}
/**
* 执行橡皮擦操作
*/
async execute() {
if (!this.beforeSnapshot || !this.afterSnapshot) {
console.warn("缺少状态快照,无法执行橡皮擦命令");
return false;
}
if (!this.fristLoad)
await this._restoreCanvasState(this.afterSnapshot); // 应用重做的状态
else await this.layerManager?.updateLayersObjectsInteractivity?.(false);
this.fristLoad = false; // 标记为非第一次加载
return true;
}
/**
* 撤销橡皮擦操作
*/
async undo() {
if (!this.beforeSnapshot) {
console.warn("缺少擦除前的状态快照,无法撤销");
return false;
}
// 恢复到擦除前的状态
await this._restoreCanvasState(this.beforeSnapshot);
return true;
}
/**
* 恢复画布状态
* @param {Object} snapshot 状态快照
* @private
*/
async _restoreCanvasState(snapshot) {
// 对比 eraser erasable 两个属性如果当前对象的eraser属性和erasable属性不一致则需要更新对象的eraser属性
if (!snapshot || !snapshot.objects) return;
// 优化渲染 - 统一批处理 支持异步回调 防止闪屏
await optimizeCanvasRendering(this.canvas, async () => {
return new Promise((resolve) => {
this.canvas.loadFromJSON(snapshot, async () => {
// 恢复图层关联
this._restoreObjectLayerAssociations();
// 确保所有对象的交互性正确设置
await this.layerManager?.updateLayersObjectsInteractivity?.(false);
resolve();
});
});
});
}
/**
* 恢复对象与图层的关联关系
* @private
*/
_restoreObjectLayerAssociations() {
if (!this.layerManager) return;
const canvasObjects = this.canvas.getObjects();
restoreObjectLayerAssociations(this.layerManager?.layers?.value, canvasObjects);
}
}