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 []; } } }