feat: 优化跨层级移动和套索抠图命令,支持异步执行,改进画布刷新逻辑,新增背景裁剪选项
This commit is contained in:
@@ -977,7 +977,6 @@ export class CanvasManager {
|
||||
}
|
||||
|
||||
this.layers.value = tempLayers;
|
||||
debugger;
|
||||
|
||||
// this.canvasWidth.value = parsedJson.canvasWidth || this.width;
|
||||
// this.canvasHeight.value = parsedJson.canvasHeight || this.height;
|
||||
@@ -1039,8 +1038,10 @@ export class CanvasManager {
|
||||
// 使用LayerSort工具重新排列画布对象(如果可用)
|
||||
await this?.layerManager?.layerSort?.rearrangeObjects();
|
||||
|
||||
this.layerManager.activeLayerId.value =
|
||||
this.layers.value[0]?.id || parsedJson?.activeLayerId || null;
|
||||
this.layerManager.activeLayerId.value = this.layers.value[0]
|
||||
.children?.length
|
||||
? this.layers.value[0].children[0].id
|
||||
: this.layers.value[0]?.id || parsedJson?.activeLayerId || null;
|
||||
|
||||
// // 如果检测到红绿图模式内容,进行缩放调整
|
||||
// if (this.enabledRedGreenMode) {
|
||||
|
||||
@@ -28,6 +28,7 @@ export class ExportManager {
|
||||
const {
|
||||
isContainBg = false,
|
||||
isContainFixed = false,
|
||||
isCropByBg = false, // 是否使用背景大小裁剪
|
||||
layerId = "",
|
||||
layerIdArray = [],
|
||||
expPicType = "png",
|
||||
@@ -43,7 +44,8 @@ export class ExportManager {
|
||||
layerId,
|
||||
expPicType,
|
||||
isRedGreenMode,
|
||||
restoreOpacityInRedGreen
|
||||
restoreOpacityInRedGreen,
|
||||
isCropByBg
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,10 +54,11 @@ export class ExportManager {
|
||||
return this._exportMultipleLayers(
|
||||
layerIdArray,
|
||||
expPicType,
|
||||
isContainBg,
|
||||
isContainFixed,
|
||||
isRedGreenMode,
|
||||
restoreOpacityInRedGreen
|
||||
restoreOpacityInRedGreen,
|
||||
isContainBg,
|
||||
isCropByBg
|
||||
);
|
||||
}
|
||||
|
||||
@@ -65,7 +68,8 @@ export class ExportManager {
|
||||
isContainBg,
|
||||
isContainFixed,
|
||||
isRedGreenMode,
|
||||
restoreOpacityInRedGreen
|
||||
restoreOpacityInRedGreen,
|
||||
isCropByBg
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("导出图片失败:", error);
|
||||
@@ -143,7 +147,8 @@ export class ExportManager {
|
||||
isContainBg,
|
||||
isContainFixed,
|
||||
isRedGreenMode,
|
||||
restoreOpacityInRedGreen
|
||||
restoreOpacityInRedGreen,
|
||||
isCropByBg
|
||||
) {
|
||||
if (!this.layerManager) {
|
||||
throw new Error("图层管理器未初始化");
|
||||
@@ -193,7 +198,8 @@ export class ExportManager {
|
||||
isContainBg,
|
||||
isContainFixed,
|
||||
isRedGreenMode,
|
||||
restoreOpacityInRedGreen
|
||||
restoreOpacityInRedGreen,
|
||||
isCropByBg
|
||||
) {
|
||||
// 按图层顺序收集对象(从底到顶)
|
||||
const objectsToExport = this._collectObjectsByLayerOrder(
|
||||
@@ -215,13 +221,38 @@ export class ExportManager {
|
||||
restoreOpacityInRedGreen
|
||||
);
|
||||
}
|
||||
|
||||
let canvasClipPath = this.canvas.clipPath;
|
||||
if (isCropByBg) {
|
||||
const cropWidth =
|
||||
this.canvasManager?.canvasWidth?.value ||
|
||||
this.canvas?.canvasWidth ||
|
||||
this.canvas.width;
|
||||
const cropHeight =
|
||||
this.canvasManager?.canvasHeight?.value ||
|
||||
this.canvas?.canvasHeight ||
|
||||
this.canvas.height;
|
||||
canvasClipPath = new fabric.Rect({
|
||||
left: this.canvas.width / 2,
|
||||
top: this.canvas.height / 2,
|
||||
width: cropWidth,
|
||||
height: cropHeight,
|
||||
originX: "center",
|
||||
originY: "center",
|
||||
fill: "#fff",
|
||||
stroke: "transparent",
|
||||
strokeWidth: 0,
|
||||
});
|
||||
canvasClipPath.set({
|
||||
absolutePositioned: true,
|
||||
});
|
||||
canvasClipPath.setCoords();
|
||||
}
|
||||
// 普通模式使用画布尺寸
|
||||
return this._exportWithCanvasSize(
|
||||
objectsToExport,
|
||||
expPicType,
|
||||
restoreOpacityInRedGreen,
|
||||
this.canvas.clipPath
|
||||
canvasClipPath
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -336,9 +336,10 @@ export class LayerManager {
|
||||
|
||||
// 设置裁剪对象
|
||||
layers.forEach(async (layer) => {
|
||||
let clippingMaskFabricObject = null;
|
||||
if (layer.clippingMask) {
|
||||
// 反序列化 clippingMask
|
||||
const clippingMaskFabricObject = await restoreFabricObject(
|
||||
clippingMaskFabricObject = await restoreFabricObject(
|
||||
layer.clippingMask,
|
||||
this.canvas
|
||||
);
|
||||
@@ -349,80 +350,30 @@ export class LayerManager {
|
||||
// ...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) => {
|
||||
if (clippingMaskFabricObject) {
|
||||
const childObj = this.canvas
|
||||
.getObjects()
|
||||
.find((o) => o.layerId === childLayer.id);
|
||||
if (childObj) {
|
||||
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 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;
|
||||
// // }
|
||||
// }
|
||||
}
|
||||
// 如果是组图层 则给所有子对象设置裁剪对象
|
||||
if (layer.type === LayerType.GROUP || layer.children?.length > 0) {
|
||||
layer.children.forEach((childLayer) => {
|
||||
const childObj = this.canvas
|
||||
.getObjects()
|
||||
.find((o) => o.layerId === childLayer.id);
|
||||
if (childObj) {
|
||||
childObj.clipPath = clippingMaskFabricObject;
|
||||
childObj.dirty = true; // 标记为脏对象
|
||||
childObj.setCoords();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
layer.fabricObjects?.forEach((obj) => {
|
||||
const fabricObject = this.canvas
|
||||
.getObjects()
|
||||
.find((o) => o.id === obj.id);
|
||||
if (fabricObject) {
|
||||
fabricObject.clipPath = clippingMaskFabricObject;
|
||||
fabricObject.dirty = true; // 标记为脏对象
|
||||
fabricObject.setCoords();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user