feat: 添加图层缩略图生成时对遮罩对象的支持,优化图层对象的z-index处理

This commit is contained in:
bighuixiang
2025-07-15 00:15:55 +08:00
parent fc9a3eddc2
commit e31a619bd6
2 changed files with 72 additions and 4 deletions

View File

@@ -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) {

View File

@@ -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);