feat: 优化填充组图层背景命令,重构代码以提高可读性和性能
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user