Files
aida_front/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js

135 lines
4.4 KiB
JavaScript
Raw Normal View History

import { Command } from "./Command";
import { findLayerRecursively } from "../utils/layerHelper";
import { fabric } from "fabric-with-all";
import {
findObjectById,
generateId,
insertObjectAtZIndex,
removeCanvasObjectByObject,
} from "../utils/helper";
/**
* 填充组图层背景命令
*/
export class FillLayerBackgroundCommand extends Command {
constructor(options) {
super({ name: "填充组图层背景", saveState: true });
this.canvas = options.canvas;
this.layers = options.layers;
this.canvasManager = options.canvasManager;
this.layerId = options.layerId;
this.fillColor = options.fillColor;
this.oldFill = null;
this.oldFillColor = null;
this.newFill = null;
const { layer } = findLayerRecursively(this.layers.value, this.layerId);
this.layer = layer;
this.group = null;
this.originalfabricObjects = this._collectOriginalObjects(); // 记录所有的原始对象
}
async execute() {
const layer = this.layer;
// 只允许填充背景层或普通图层
if (!layer.isBackground && !layer.isFixed && !layer.fabricObjects?.length) return false;
// 记录原填充色
this.oldFill = layer.fill ?? null;
this.oldFillColor = layer.oldFillColor ?? null;
// 更新fabric对象填充
// 判断是否有遮罩层 有遮罩使用遮罩层大小 否则使用第一个大小
const originalInfo =
findObjectById(this.canvas.value, layer.fabricObjects?.[0]?.id)?.object?.getBoundingRect?.(
true,
true
) ||
layer?.clippingMask ||
layer.fabricObjects?.[0];
this.newFill = new fabric.Rect({
width: originalInfo.width,
height: originalInfo.height,
left: originalInfo.left || 0,
top: originalInfo.top || 0,
fill: this.fillColor,
layerId: this.layerId,
id: generateId("fill-"),
selectable: false,
evented: false,
originX: originalInfo.originX || "center",
originY: originalInfo.originY || "center",
scaleX: originalInfo.scaleX || 1,
scaleY: originalInfo.scaleY || 1,
});
// 判断fabricObjects是否是组是组则添加填充到最前面否则创建组
if (layer.fabricObjects && layer.fabricObjects.length > 0) {
// 如果是组,直接添加到组中
// 否则创建一个新的组 插入到原本的图层对象前面
const layerObjects = this.canvas
.getObjects()
.reverse()
.filter((obj) => obj.layerId === this.layerId);
let insertIndex =
this.canvas.getObjects()?.findIndex((obj) => obj.id === layer.fabricObjects?.[0]?.id) || 0;
insertIndex = insertIndex == -1 ? 0 : insertIndex;
this.group = new fabric.Group([this.newFill, ...layerObjects]);
this.group.set({
id: layerObjects[0]?.id || generateId("group-"),
layerId: layerObjects[0]?.layerId,
});
this.group.setCoords();
layer.fabricObjects = [this.group?.toObject?.(["id", "layerId"]) || this.group];
removeCanvasObjectByObject(this.canvas, layer.fabricObjects[0]);
insertObjectAtZIndex(this.canvas, this.group, insertIndex, false); // 插入到画布的指定位置
// 将新填充对象添加到画布
}
this.canvas.renderAll();
layer.fill = this.newFill.toObject(["id", "layerId"]);
layer.fillColor = this.fillColor;
this.canvasManager.thumbnailManager?.generateLayerThumbnail(this.layer.id);
return true;
}
async undo() {
this.layer.fillColor = this.oldFillColor;
this.layer.fill = this.oldFill;
this.group.removeWithUpdate(this.newFill);
this.canvas.remove(this.newFill);
this.canvas.renderAll();
this.canvasManager.thumbnailManager?.generateLayerThumbnail(this.layer.id);
return true;
}
_collectOriginalObjects() {
if (this.layer.children && this.layer.children.length > 0) {
// 如果是组图层收集所有子图层的fabric对象
return this.layer.children
.flatMap((child) => child.fabricObjects || [])
.map((obj) => {
return findObjectById(this.canvas.value, obj.id)?.object || obj;
});
} else if (this.layer.fabricObjects && this.layer.fabricObjects.length > 0) {
// 如果是普通图层直接返回其fabric对象
return this.layer.fabricObjects.map((obj) => {
return findObjectById(this.canvas.value, obj.id)?.object || obj;
});
} else {
// 如果没有fabric对象返回空数组
return [];
}
}
}