feat: 添加图层缩略图生成时对遮罩对象的支持,优化图层对象的z-index处理
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user