feat: 优化选区功能,修复部分bug

This commit is contained in:
bighuixiang
2025-07-10 01:01:46 +08:00
parent 943b49c1d7
commit 7359fe2f9a
11 changed files with 1667 additions and 126 deletions

View File

@@ -407,8 +407,8 @@ export class CanvasManager {
// 居中所有画布元素,包括背景层和其他元素
this.centerAllObjects();
// 重新渲染画布使变更生效
this.canvas.renderAll();
// // 重新渲染画布使变更生效
// this.canvas.renderAll();
}
/**
@@ -510,7 +510,7 @@ export class CanvasManager {
}
// 重新渲染画布
this.canvas.renderAll();
// this.canvas.renderAll();
}
/**
@@ -958,6 +958,9 @@ export class CanvasManager {
// 解析JSON字符串
try {
const parsedJson = JSON.parse(json);
this.canvasWidth.value = parsedJson.canvasWidth || this.width;
this.canvasHeight.value = parsedJson.canvasHeight || this.height;
this.canvasColor.value = parsedJson.canvasColor || this.backgroundColor;
return new Promise(async (resolve, reject) => {
const tempLayers = JSON.parse(parsedJson?.layers) || [];
@@ -974,6 +977,7 @@ export class CanvasManager {
}
this.layers.value = tempLayers;
debugger;
// this.canvasWidth.value = parsedJson.canvasWidth || this.width;
// this.canvasHeight.value = parsedJson.canvasHeight || this.height;

View File

@@ -67,6 +67,8 @@ import {
} from "../utils/helper";
import { message } from "ant-design-vue";
import { fabric } from "fabric-with-all";
import { getOriginObjectInfo } from "../utils/layerUtils";
import { restoreFabricObject } from "../utils/objectHelper";
/**
* 图层管理器 - 负责管理画布上的所有图层
@@ -333,52 +335,94 @@ export class LayerManager {
});
// 设置裁剪对象
layers.forEach((layer) => {
layers.forEach(async (layer) => {
if (layer.clippingMask) {
const activeObject = this.canvas.getActiveObject();
if (activeObject?._objects?.length > 1) {
console.log(activeObject?._objects?.length);
return false; // 如果是多选对象,则不设置裁剪路径
}
// 反序列化 clippingMask
const clippingMaskFabricObject = await restoreFabricObject(
layer.clippingMask,
this.canvas
);
clippingMaskFabricObject.clipPath = null;
clippingMaskFabricObject.set({
// 设置绝对定位
// ...getOriginObjectInfo(layer.clippingMask), // 恢复原定位
absolutePositioned: true,
});
// const activeObject = this.canvas.getActiveObject();
// if (activeObject?._objects?.length > 1) {
// const { object } = findObjectById(
// this.canvas,
// layer.clippingMask?.id
// );
// if (!object) return;
// const tempClipPath = fabric.util.object.clone(object);
// tempClipPath.clipPath = null;
// tempClipPath.set({
// // 设置绝对定位
// ...getOriginObjectInfo(layer.clippingMask), // 恢复原定位
// absolutePositioned: true,
// });
// activeObject.clipPath = tempClipPath;
// // 确保选择组正确渲染
// // activeObject.setCoords();
// console.log(activeObject?._objects?.length);
// return; // 如果是多选对象,则不设置裁剪路径
// }
// 如果是组图层 则给所有子对象设置裁剪对象
if (layer.type === LayerType.GROUP || layer.children?.length > 0) {
layer.children.forEach((childLayer) => {
const { object } = findObjectById(
this.canvas,
layer.clippingMask?.id
);
if (object) {
const tempClipPath = fabric.util.object.clone(object);
tempClipPath.clipPath = null;
tempClipPath.set({
// 设置绝对定位
// ...layer.clippingMask, // 恢复原定位
absolutePositioned: true,
});
if (clippingMaskFabricObject) {
const childObj = this.canvas
.getObjects()
.find((o) => o.layerId === childLayer.id);
if (childObj) {
childObj.clipPath = tempClipPath;
childObj.clipPath = clippingMaskFabricObject;
}
}
// const { object } = findObjectById(
// this.canvas,
// layer.clippingMask?.id
// );
// if (object) {
// const tempClipPath = fabric.util.object.clone(object);
// tempClipPath.clipPath = null;
// tempClipPath.set({
// // 设置绝对定位
// // ...layer.clippingMask, // 恢复原定位
// ...getOriginObjectInfo(layer.clippingMask),
// absolutePositioned: true,
// });
// const childObj = this.canvas
// .getObjects()
// .find((o) => o.layerId === childLayer.id);
// if (childObj) {
// childObj.clipPath = tempClipPath;
// }
// }
});
} else {
const { object } = findObjectById(
this.canvas,
layer.clippingMask?.id
);
if (object) {
const tempClipPath = fabric.util.object.clone(object);
tempClipPath.clipPath = null; // 确保克隆的遮罩没有clipPath
tempClipPath.set({
// 设置绝对定位
// ...layer.clippingMask, // 恢复原定位
absolutePositioned: true,
});
obj.clipPath = tempClipPath;
}
} else if (clippingMaskFabricObject) {
obj.clipPath = clippingMaskFabricObject;
}
// {
// // const { object } = findObjectById(
// // this.canvas,
// // layer.clippingMask?.id
// // );
// // if (object) {
// // const tempClipPath = fabric.util.object.clone(object);
// // tempClipPath.clipPath = null; // 确保克隆的遮罩没有clipPath
// // tempClipPath.set({
// // // 设置绝对定位
// // // ...layer.clippingMask, // 恢复原定位
// // ...getOriginObjectInfo(layer.clippingMask),
// // absolutePositioned: true,
// // });
// // obj.clipPath = tempClipPath;
// // }
// }
}
});
}
@@ -932,17 +976,16 @@ export class LayerManager {
// 设置激活当前图层下画布中的所有对象,并变成选择组
setAllActiveGroupLayerCanvasObject(layer) {
// 获取当前图层下所有元素
let layerMask = null;
// 选择当前组下所有画布元素
const allObjects = layer.children.reduce((acc, child) => {
// 如果子图层有fabricObjects则添加到结果数组
child?.fabricObjects?.forEach((obj) => {
const { object } = findObjectById(this.canvas, obj.id);
if (object) {
if (!layerMask) {
layerMask = fabric.util.object.clone(object.clipPath);
}
object.clipPath = null; // 确保克隆的遮罩没有clipPath
// if (!layerMask) {
// layerMask = fabric.util.object.clone(object.clipPath);
// }
// object.clipPath = null; // 确保克隆的遮罩没有clipPath
acc.push(object);
}
});
@@ -950,10 +993,10 @@ export class LayerManager {
if (child?.fabricObject) {
const { object } = findObjectById(this.canvas, child?.fabricObject.id);
if (object) {
if (!layerMask) {
layerMask = fabric.util.object.clone(object.clipPath);
}
object.clipPath = null; // 确保克隆的遮罩没有clipPath
// if (!layerMask) {
// layerMask = fabric.util.object.clone(object.clipPath);
// }
// object.clipPath = null; // 确保克隆的遮罩没有clipPath
acc.push(object);
}
}
@@ -967,17 +1010,48 @@ export class LayerManager {
// 如果有对象,创建选择组
this.canvas.discardActiveObject(); // 取消当前活动对象
this.canvas.renderAll(); // 确保画布渲染
// const { object } = findObjectById(this.canvas, layer.clippingMask?.id);
// 选中多个对象,不是创建组
// 多个对象时创建活动选择组
const activeSelection = new fabric.ActiveSelection(allObjects, {
let activeSelection = new fabric.ActiveSelection(allObjects, {
canvas: this.canvas,
});
activeSelection.clipPath = layerMask; // 保留第一个对象的裁剪路径
// if (object) {
// const tempClipPath = fabric.util.object.clone(object);
// tempClipPath.clipPath = null;
// tempClipPath.set({
// // 设置绝对定位
// // ...layer.clippingMask, // 恢复原定位
// ...getOriginObjectInfo(layer.clippingMask),
// absolutePositioned: true,
// });
// activeSelection.clipPath = tempClipPath; // 保留第一个对象的裁剪路径
// }
// // 监听选择取消事件,恢复原始裁剪路径
// const restoreClipPaths = () => {
// allObjects.forEach((obj) => {
// if (obj._originalClipPath !== undefined) {
// obj.clipPath = obj._originalClipPath;
// delete obj._originalClipPath;
// }
// });
// this.canvas.off("selection:cleared", restoreClipPaths);
// this.canvas.off("selection:updated", restoreClipPaths);
// };
// this.canvas.on("selection:cleared", restoreClipPaths);
// this.canvas.on("selection:updated", restoreClipPaths);
// 设置活动选择组的属性
this.canvas.setActiveObject(activeSelection);
this.canvas.renderAll();
activeSelection = null; // 清理引用,避免内存泄漏
// 确保选择组正确渲染
// activeSelection.setCoords();
}
}