diff --git a/src/component/Canvas/CanvasEditor/commands/RasterizeLayerCommand.js b/src/component/Canvas/CanvasEditor/commands/RasterizeLayerCommand.js index 6c5d7259..925b7540 100644 --- a/src/component/Canvas/CanvasEditor/commands/RasterizeLayerCommand.js +++ b/src/component/Canvas/CanvasEditor/commands/RasterizeLayerCommand.js @@ -228,6 +228,18 @@ export class RasterizeLayerCommand extends Command { const objectsWithZIndex = []; this.layersToRasterize.forEach((layer) => { + if (layer.fill) { + const { object } = findObjectById(this.canvas, layer.fill.id); + if (object) { + // 获取对象在画布中的z-index(数组索引) + const zIndex = allCanvasObjects.indexOf(object); + objectsWithZIndex.push({ + object: object, + zIndex: zIndex, + layerObj: layer.fill, + }); + } + } if (layer.fabricObjects && layer.fabricObjects.length > 0) { layer.fabricObjects.forEach((layerObj) => { if (layerObj && layerObj.id) { @@ -459,11 +471,27 @@ export class ExportLayerToImageCommand extends Command { this.canvas.discardActiveObject(); this.canvas.renderAll(); + // 重新创建遮罩对象 + let clippingMaskFabricObject = null; + if (this.layer?.clippingMask) { + // 重新创建遮罩对象 + clippingMaskFabricObject = await restoreFabricObject(this.layer?.clippingMask, this.canvas); + + clippingMaskFabricObject.clipPath = null; + clippingMaskFabricObject.set({ + absolutePositioned: true, + }); + + clippingMaskFabricObject.dirty = true; + clippingMaskFabricObject.setCoords(); + } + // 创建图像 const imageBase64 = await createRasterizedImage({ canvas: this.canvas, fabricObjects: this.objectsToRasterize, isReturenDataURL: true, + maskObject: clippingMaskFabricObject || null, // 不处理遮罩 }); // 模拟浏览器下载 @@ -504,6 +532,18 @@ export class ExportLayerToImageCommand extends Command { const objectsWithZIndex = []; this.layersToRasterize.forEach((layer) => { + if (layer.fill) { + const { object } = findObjectById(this.canvas, layer.fill.id); + if (object) { + // 获取对象在画布中的z-index(数组索引) + const zIndex = allCanvasObjects.indexOf(object); + objectsWithZIndex.push({ + object: object, + zIndex: zIndex, + layerObj: layer.fill, + }); + } + } if (layer.fabricObjects && layer.fabricObjects.length > 0) { layer.fabricObjects.forEach((layerObj) => { if (layerObj && layerObj.id) { diff --git a/src/component/Canvas/CanvasEditor/managers/ThumbnailManager.js b/src/component/Canvas/CanvasEditor/managers/ThumbnailManager.js index bb8840dd..79f41375 100644 --- a/src/component/Canvas/CanvasEditor/managers/ThumbnailManager.js +++ b/src/component/Canvas/CanvasEditor/managers/ThumbnailManager.js @@ -1,5 +1,6 @@ import { findObjectById } from "../utils/helper"; import { findLayerRecursively } from "../utils/layerHelper"; +import { restoreFabricObject } from "../utils/objectHelper"; import { createRasterizedImage } from "../utils/rasterizedImage"; /** @@ -23,11 +24,11 @@ export class ThumbnailManager { */ async generateLayerThumbnail(layerId) { const fabricObjects = this._collectLayersAndObjects(layerId); + const { layer } = findLayerRecursively(this.layers.value, layerId); if (!fabricObjects || fabricObjects.length === 0) { console.warn("⚠️ 无法生成缩略图:没有可栅格化的对象 返回空缩略图"); // 如果没有对象,返回默认缩略图 - const { layer } = findLayerRecursively(this.layers.value, layerId); if (layer) { layer.thumbnailUrl = this.defaultThumbnail; // 更新图层对象的缩略图 } @@ -38,7 +39,7 @@ export class ThumbnailManager { fabricObjects.length > 0 && requestIdleCallback(() => { setTimeout(async () => { - const base64 = await this._generateLayerThumbnailNow(fabricObjects); + const base64 = await this._generateLayerThumbnailNow(fabricObjects, layer); // this.layerThumbnails.set(layerId, base64); try { const { layer, parent } = findLayerRecursively(this.layers.value, layerId); @@ -79,16 +80,30 @@ export class ThumbnailManager { } // 生成图片 - async _generateLayerThumbnailNow(fabricObjects) { + async _generateLayerThumbnailNow(fabricObjects, layer) { if (!fabricObjects || fabricObjects.length === 0) { console.warn("⚠️ 没有对象需要生成缩略图,返回默认缩略图"); return this.defaultThumbnail; } try { + let clippingMaskFabricObject = null; + if (layer?.clippingMask) { + // 重新创建遮罩对象 + clippingMaskFabricObject = await restoreFabricObject(layer?.clippingMask, this.canvas); + + clippingMaskFabricObject.clipPath = null; + clippingMaskFabricObject.set({ + absolutePositioned: true, + }); + + clippingMaskFabricObject.dirty = true; + clippingMaskFabricObject.setCoords(); + } + return await createRasterizedImage({ canvas: this.canvas, // 画布对象 必填 fabricObjects, // 要栅格化的对象列表 - 按顺序 必填 - // maskObject = null, // 用于裁剪的对象 - 可选 // TODO: 后期看是否需要裁剪 + maskObject: clippingMaskFabricObject || null, // 用于裁剪的对象 - 可选 trimWhitespace: true, // 是否裁剪空白区域 trimPadding: 2, // 裁剪边距 quality: 0.2, // 图像质量 @@ -128,6 +143,19 @@ export class ThumbnailManager { const objectsWithZIndex = []; layersToRasterize.forEach((layer) => { + if (layer.fill) { + const { object } = findObjectById(this.canvas, layer.fill.id); + if (object) { + // 获取对象在画布中的z-index(数组索引) + const zIndex = allCanvasObjects.indexOf(object); + objectsWithZIndex.push({ + object: object, + zIndex: zIndex, + layerObj: layer.fill, + }); + } + } + if (layer.fabricObject) { // 如果图层本身有fabricObject,直接添加 const { object } = findObjectById(this.canvas, layer.fabricObject.id);