feat: 优化跨层级移动和套索抠图命令,支持异步执行,改进画布刷新逻辑,新增背景裁剪选项
This commit is contained in:
@@ -181,7 +181,7 @@ export class CrossLevelMoveCommand extends Command {
|
||||
return ancestor ? checkChildren(ancestor.children) : false;
|
||||
}
|
||||
|
||||
execute() {
|
||||
async execute() {
|
||||
console.log("🎯 执行跨层级移动命令:", {
|
||||
layerId: this.layerId,
|
||||
from: this.fromContainerType,
|
||||
@@ -220,10 +220,13 @@ export class CrossLevelMoveCommand extends Command {
|
||||
this.saveAfterState();
|
||||
|
||||
// 刷新画布
|
||||
if (this.canvas) {
|
||||
this.canvas.renderAll();
|
||||
console.log("🎨 画布已刷新");
|
||||
}
|
||||
// if (this.canvas) {
|
||||
// this.canvas.renderAll();
|
||||
// console.log("🎨 画布已刷新");
|
||||
// }
|
||||
|
||||
await this.layerManager?.updateLayersObjectsInteractivity();
|
||||
this.canvas?.renderAll();
|
||||
|
||||
console.log("✅ 跨层级移动命令执行成功");
|
||||
return true;
|
||||
@@ -248,7 +251,7 @@ export class CrossLevelMoveCommand extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
undo() {
|
||||
async undo() {
|
||||
if (!this.beforeState) {
|
||||
throw new Error("没有保存的前置状态,无法撤销");
|
||||
}
|
||||
@@ -262,14 +265,10 @@ export class CrossLevelMoveCommand extends Command {
|
||||
// 恢复fabric对象状态
|
||||
this.restoreFabricObjectStates(this.beforeState.fabricObjects);
|
||||
|
||||
await this.layerManager?.updateLayersObjectsInteractivity();
|
||||
this.canvas?.renderAll();
|
||||
// 刷新画布
|
||||
if (this.canvas) {
|
||||
// 使用 requestAnimationFrame 确保DOM更新完成后再渲染
|
||||
requestAnimationFrame(() => {
|
||||
this.canvas.renderAll();
|
||||
});
|
||||
}
|
||||
|
||||
this.canvas?.renderAll();
|
||||
console.log("✅ 跨层级移动命令撤销成功");
|
||||
return true;
|
||||
} catch (error) {
|
||||
@@ -331,7 +330,7 @@ export class CrossLevelMoveCommand extends Command {
|
||||
/**
|
||||
* 重做命令
|
||||
*/
|
||||
redo() {
|
||||
async redo() {
|
||||
if (!this.afterState) {
|
||||
throw new Error("没有保存的后置状态,无法重做");
|
||||
}
|
||||
@@ -345,13 +344,9 @@ export class CrossLevelMoveCommand extends Command {
|
||||
// 恢复fabric对象状态
|
||||
this.restoreFabricObjectStates(this.afterState.fabricObjects);
|
||||
|
||||
await this.layerManager?.updateLayersObjectsInteractivity();
|
||||
// 刷新画布
|
||||
if (this.canvas) {
|
||||
// 使用 requestAnimationFrame 确保DOM更新完成后再渲染
|
||||
requestAnimationFrame(() => {
|
||||
this.canvas.renderAll();
|
||||
});
|
||||
}
|
||||
this.canvas?.renderAll();
|
||||
|
||||
console.log("✅ 跨层级移动命令重做成功");
|
||||
return true;
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
createLayer,
|
||||
findInChildLayers,
|
||||
LayerType,
|
||||
OperationType,
|
||||
} from "../utils/layerHelper.js";
|
||||
import { createRasterizedImage } from "../utils/selectionToImage.js";
|
||||
import { CompositeCommand, Command } from "./Command.js";
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
} from "./LayerCommands.js";
|
||||
import { fabric } from "fabric-with-all";
|
||||
import { generateId } from "../utils/helper.js";
|
||||
import { ToolCommand } from "./ToolCommands.js";
|
||||
|
||||
/**
|
||||
* 套索抠图命令
|
||||
@@ -256,16 +258,16 @@ export class LassoCutoutCommand extends CompositeCommand {
|
||||
// this.fabricImage.toObject("id", "layerId", "layerName", "parentId"),
|
||||
// ];
|
||||
// 2. 删除原图层命令
|
||||
const removeOriginalLayerCmd = new RemoveLayerCommand({
|
||||
canvas: this.canvas,
|
||||
layers: this.layerManager.layers,
|
||||
layerId: this.originalLayer.id,
|
||||
activeLayerId: this.layerManager.activeLayerId,
|
||||
});
|
||||
// const removeOriginalLayerCmd = new RemoveLayerCommand({
|
||||
// canvas: this.canvas,
|
||||
// layers: this.layerManager.layers,
|
||||
// layerId: this.originalLayer.id,
|
||||
// activeLayerId: this.layerManager.activeLayerId,l
|
||||
// });
|
||||
|
||||
// 执行删除原图层命令
|
||||
await removeOriginalLayerCmd.execute();
|
||||
this.executedCommands.push(removeOriginalLayerCmd);
|
||||
// // 执行删除原图层命令
|
||||
// await removeOriginalLayerCmd.execute();
|
||||
// this.executedCommands.push(removeOriginalLayerCmd);
|
||||
|
||||
this.groupLayer.clippingMask = clippingMask.toObject(["id", "layerId"]); // 设置组图层的fabricObject为遮罩图像
|
||||
|
||||
@@ -275,6 +277,21 @@ export class LassoCutoutCommand extends CompositeCommand {
|
||||
|
||||
this.layerManager.activeLayerId.value = selectLayer.id; // 设置新组图层为活动图层
|
||||
|
||||
// 切换工具到选择模式
|
||||
// 3. 切换工具到选择模式命令
|
||||
if (this.toolManager) {
|
||||
const toolCmd = new ToolCommand({
|
||||
toolManager: this.toolManager,
|
||||
tool: OperationType.SELECT,
|
||||
previousTool: this.toolManager.getCurrentTool(),
|
||||
});
|
||||
|
||||
// 执行工具切换命令
|
||||
await toolCmd.execute();
|
||||
this.commands.push(toolCmd);
|
||||
this.executedCommands.push(toolCmd);
|
||||
}
|
||||
|
||||
this.canvas.discardActiveObject();
|
||||
// this.canvas.setActiveObject(this.fabricImage);
|
||||
await this.layerManager.updateLayersObjectsInteractivity(true);
|
||||
|
||||
@@ -2033,8 +2033,12 @@ export class LayerObjectsToGroupCommand extends Command {
|
||||
|
||||
const allObjects = [...originalObjects, ...newObjects];
|
||||
|
||||
const clipPath = allObjects?.[0]?.clipPath || null;
|
||||
// 从画布中移除所有要组合的对象
|
||||
allObjects.forEach((obj) => {
|
||||
obj.clipPath = null;
|
||||
obj.dirty = true; // 标记为脏对象
|
||||
// obj.setCoords();
|
||||
obj.opacity = 1;
|
||||
removeCanvasObjectByObject(this.canvas, obj);
|
||||
});
|
||||
@@ -2052,6 +2056,10 @@ export class LayerObjectsToGroupCommand extends Command {
|
||||
// 添加组对象到画布
|
||||
this.canvas.add(groupObject);
|
||||
|
||||
groupObject.clipPath = clipPath; // 恢复剪切路径
|
||||
groupObject.dirty = true; // 标记为脏对象
|
||||
groupObject.setCoords();
|
||||
|
||||
// 更新图层的对象列表
|
||||
// this.activeLayer.fabricObjects = [groupObject];
|
||||
this.activeLayer.fabricObjects = [
|
||||
|
||||
Reference in New Issue
Block a user