135 lines
4.4 KiB
JavaScript
135 lines
4.4 KiB
JavaScript
|
|
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 [];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|