diff --git a/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js b/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js index e4f5622c..5aa051d5 100644 --- a/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js +++ b/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js @@ -24,7 +24,10 @@ export class FillGroupLayerBackgroundCommand extends Command { this.oldFillColor = null; this.newFill = null; - const { layer, parent } = findLayerRecursively(this.layers.value, this.layerId); + const { layer, parent } = findLayerRecursively( + this.layers.value, + this.layerId + ); this.layer = layer; this.parent = parent; @@ -35,11 +38,13 @@ export class FillGroupLayerBackgroundCommand extends Command { // 计算所有对象的边界 this.originalInfo = this._getCurrentObjectsBoundingRect(); + + this.firstObj = null; // 用于存储组图层的原始对象 } async execute() { const layer = this.layer; - if (!layer.isBackground && !layer.isFixed && !layer.fabricObjects?.length) return false; + if (!layer) return false; this.oldFill = layer.fill ?? null; this.oldFillColor = layer.oldFillColor ?? null; @@ -47,7 +52,10 @@ export class FillGroupLayerBackgroundCommand extends Command { // 构建填充对象 let clippingMaskFabricObject = null; if (layer.clippingMask) { - clippingMaskFabricObject = await restoreFabricObject(layer.clippingMask, this.canvas); + clippingMaskFabricObject = await restoreFabricObject( + layer.clippingMask, + this.canvas + ); clippingMaskFabricObject.clipPath = null; clippingMaskFabricObject.set({ absolutePositioned: true }); this.newFill = new fabric.Rect({ @@ -90,9 +98,61 @@ export class FillGroupLayerBackgroundCommand extends Command { } // 判断fabricObjects是否是组对象 - const firstObj = layer.fabricObjects?.[0]; + const firstObj = layer.fabricObjects?.[0] || null; + // 如果没有找到第一个对象,则直接添加到当前画布 + if (!firstObj) { + if (this?.parent?.clippingMask) { + clippingMaskFabricObject = await restoreFabricObject( + this.parent.clippingMask, + this.canvas + ); + clippingMaskFabricObject.clipPath = null; + clippingMaskFabricObject.set({ absolutePositioned: true }); + this.newFill = new fabric.Rect({ + width: clippingMaskFabricObject.width, + height: clippingMaskFabricObject.height, + left: clippingMaskFabricObject.left || 0, + top: clippingMaskFabricObject.top || 0, + fill: this.fillColor, + layerId: this.layerId, + id: this.oldFill?.id || generateId("fill-"), + selectable: false, + evented: false, + originX: clippingMaskFabricObject.originX || "center", + originY: clippingMaskFabricObject.originY || "center", + scaleX: clippingMaskFabricObject.scaleX || 1, + scaleY: clippingMaskFabricObject.scaleY || 1, + }); + this.newFill.clipPath = clippingMaskFabricObject; // 设置填充的遮罩 + this.newFill.dirty = true; // 标记为脏,以便重新 + this.canvas.add(this.newFill); + this.firstObj = this.newFill; + layer.fabricObjects = [ + this.newFill.toObject(["id", "layerId"]) || this.newFill, + ]; + layer.fill = null; // this.newFill.toObject(["id", "layerId"]); + layer.fillColor = this.fillColor; + // 取消激活对象 + + this.canvas.discardActiveObject(); // 取消当前活动对象 + // 重新排序 + await this.layerManager?.sortLayersWithTool?.(); + // 更新画布上对象的可选择状态 + await this.layerManager?.updateLayersObjectsInteractivity?.(); + this.canvas.renderAll(); + + this.canvasManager.thumbnailManager?.generateLayerThumbnail( + this.layer.id + ); + } + + return false; + } const canvasObj = findObjectById(this.canvas, firstObj?.id)?.object; - if ((canvasObj && canvasObj.type === "group") || canvasObj._objects?.length > 0) { + if ( + (canvasObj && canvasObj.type === "group") || + canvasObj._objects?.length > 0 + ) { this.newFill.set({ left: 0, top: 0, @@ -109,13 +169,17 @@ export class FillGroupLayerBackgroundCommand extends Command { } else if (layer.fabricObjects && layer.fabricObjects.length > 0) { // 普通对象,组成新组 const layerObjects = - this.canvas.getObjects().filter((obj) => obj.layerId === this.layerId) || []; + this.canvas + .getObjects() + .filter((obj) => obj.layerId === this.layerId) || []; // layerObjects?.forEach((obj) => { // obj.clipPath = null; // obj.dirty = true; // obj.setCoords(); // }); - let insertIndex = this.canvas.getObjects()?.findIndex((obj) => obj.id === firstObj?.id) ?? 0; + let insertIndex = + this.canvas.getObjects()?.findIndex((obj) => obj.id === firstObj?.id) ?? + 0; insertIndex = insertIndex === -1 ? 0 : insertIndex; layerObjects.forEach((obj) => { obj.clipPath = null; @@ -129,12 +193,17 @@ export class FillGroupLayerBackgroundCommand extends Command { // this.group.setObjectsCoords(); // this.group.dirty = true; // 标记为脏对象 if (this.parent?.clippingMask) { - const clipPath = await restoreFabricObject(this.parent?.clippingMask, this.canvas); + const clipPath = await restoreFabricObject( + this.parent?.clippingMask, + this.canvas + ); clipPath.clipPath = null; clipPath.set({ absolutePositioned: true }); this.group.clipPath = clipPath; } - layer.fabricObjects = [this.group.toObject(["id", "layerId"]) || this.group]; + layer.fabricObjects = [ + this.group.toObject(["id", "layerId"]) || this.group, + ]; // removeCanvasObjectByObject(this.canvas, layerObjects?.[0]); insertObjectAtZIndex(this.canvas, this.group, insertIndex, false, true); } @@ -160,11 +229,29 @@ export class FillGroupLayerBackgroundCommand extends Command { this.layer.fillColor = this.oldFillColor; this.layer.fill = this.oldFill; + if (!this.originalInfo && this.firstObj) { + this.canvas.discardActiveObject(); + this.canvas.remove(this.firstObj); + this.canvas.renderAll(); + this.canvasManager.thumbnailManager?.generateLayerThumbnail( + this.parent.id + ); + this.canvasManager.thumbnailManager?.generateLayerThumbnail( + this.layer.id + ); + this.layer.fabricObjects = []; + return false; + } + // 判断fabricObjects是否是组对象 const firstObj = this.layer.fabricObjects?.[0]; - const canvasObj = this.group || findObjectById(this.canvas, firstObj?.id)?.object; + const canvasObj = + this.group || findObjectById(this.canvas, firstObj?.id)?.object; - if ((canvasObj && canvasObj.type === "group") || canvasObj?._objects?.length > 0) { + if ( + (canvasObj && canvasObj.type === "group") || + canvasObj?._objects?.length > 0 + ) { // 移除新添加的填充对象 if (canvasObj._objects?.[0] === this.newFill) { canvasObj._objects.shift(); @@ -205,7 +292,10 @@ export class FillGroupLayerBackgroundCommand extends Command { .map((obj) => { return findObjectById(this.canvas.value, obj.id)?.object || obj; }); - } else if (this.layer?.fabricObjects && this.layer?.fabricObjects?.length > 0) { + } 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; @@ -222,11 +312,17 @@ export class FillGroupLayerBackgroundCommand extends Command { minTop = Infinity, maxRight = -Infinity, maxBottom = -Infinity; - console.log("计算当前所有对象的边界信息:===>", this.originalfabricObjects.length); + console.log( + "计算当前所有对象的边界信息:===>", + this.originalfabricObjects.length + ); this.originalfabricObjects?.forEach((obj) => { const { object } = findObjectById(this.canvas, obj.id) || {}; if (object) { - const rect = object.getBoundingRect({ absolute: true, includeStroke: false }); + const rect = object.getBoundingRect({ + absolute: true, + includeStroke: false, + }); minLeft = Math.min(minLeft, rect.left); minTop = Math.min(minTop, rect.top); maxRight = Math.max(maxRight, rect.left + rect.width);