feat: 液化撤销问题修复+选取更改逻辑+右键删除组图层问题修复

This commit is contained in:
bighuixiang
2025-07-09 00:22:03 +08:00
parent 5cc93aeba4
commit 943b49c1d7
9 changed files with 1668 additions and 545 deletions

View File

@@ -411,43 +411,63 @@ export class RemoveLayerCommand extends Command {
this.removedLayer = this.layers.value[this.layerIndex];
this.isActiveLayer = this.layerId === this.activeLayerId.value;
// 从Canvas中找到真实对象并备份确保撤销和重做时对象的一致性
// 从Canvas中找到真实对象并备份包括当前图层及其所有子图层的对象
this.originalObjects = [];
if (this.removedLayer) {
// 从画布中获取真实的对象引用
this.originalObjects = this.canvas.getObjects().filter((obj) => {
return obj.layerId === this.layerId;
});
this.originalObjects = this._collectAllLayerObjects(this.removedLayer);
}
// 备份原活动图层ID
this.originalActiveLayerId = this.activeLayerId.value;
}
/**
* 收集图层及其所有子图层的画布对象
* @param {Object} layer 要收集对象的图层
* @returns {Array} 所有相关的画布对象
* @private
*/
_collectAllLayerObjects(layer) {
const allObjects = [];
// 收集当前图层的对象
const layerObjects = this.canvas.getObjects().filter((obj) => {
return obj.layerId === layer.id;
});
allObjects.push(...layerObjects);
// 如果图层有特殊的fabricObject属性如背景图层
if (layer.fabricObject) {
const { object } = findObjectById(this.canvas, layer.fabricObject.id);
if (object && !allObjects.includes(object)) {
allObjects.push(object);
}
}
// 递归收集子图层的对象
if (layer.children && Array.isArray(layer.children)) {
layer.children.forEach((childLayer) => {
const childObjects = this._collectAllLayerObjects(childLayer);
allObjects.push(...childObjects);
});
}
return allObjects;
}
execute() {
if (this.layerIndex === -1 || !this.removedLayer) {
console.error(`图层 ${this.layerId} 不存在`);
return false;
}
// 从画布中移除图层中的所有真实对象
// 从画布中移除图层及其所有子图层中的真实对象
this.originalObjects.forEach((obj) => {
if (this.canvas.getObjects().includes(obj)) {
this.canvas.remove(obj);
}
});
// 如果是背景图层,移除特殊对象
if (this.removedLayer.isBackground && this.removedLayer.fabricObject) {
const { object } = findObjectById(
this.canvas,
this.removedLayer.fabricObject.id
);
if (object) {
this.canvas.remove(object);
}
}
// 从图层列表中删除
this.layers.value.splice(this.layerIndex, 1);
@@ -470,7 +490,7 @@ export class RemoveLayerCommand extends Command {
}
console.log(
`✅ 已移除图层: ${this.removedLayer.name} (ID: ${this.layerId})`
`✅ 已移除图层: ${this.removedLayer.name} (ID: ${this.layerId}),包含 ${this.originalObjects.length} 个对象`
);
return true;
}
@@ -482,26 +502,18 @@ export class RemoveLayerCommand extends Command {
// 使用优化渲染批处理恢复真实对象到画布
optimizeCanvasRendering(this.canvas, () => {
this.originalObjects.forEach((obj) => {
// 恢复对象到画布
this.canvas.add(obj);
// 确保对象的图层信息正确
obj.layerId = this.layerId;
obj.layerName = this.removedLayer.name;
obj.setCoords(); // 更新坐标
});
// 如果是背景图层,恢复特殊对象
if (this.removedLayer.isBackground && this.removedLayer.fabricObject) {
// 检查对象是否已在画布中
const { object } = findObjectById(
this.canvas,
this.removedLayer.fabricObject.id
);
if (!object) {
this.canvas.add(this.removedLayer.fabricObject);
}
}
// 倒序添加对象,确保下标越小的子图层在画布中越靠前
this.originalObjects
.slice()
.reverse()
.forEach((obj) => {
// 确保对象不在画布中才添加,避免重复添加
if (!this.canvas.getObjects().includes(obj)) {
this.canvas.add(obj);
// 确保对象的坐标正确
obj.setCoords();
}
});
});
// 如果删除的是当前活动图层,恢复活动图层
@@ -510,7 +522,7 @@ export class RemoveLayerCommand extends Command {
}
console.log(
`↩️ 已恢复图层: ${this.removedLayer.name} (ID: ${this.layerId})`
`↩️ 已恢复图层: ${this.removedLayer.name} (ID: ${this.layerId}),包含 ${this.originalObjects.length} 个对象`
);
}
}