feat(CanvasManager): enhance image layer management and event handling

This commit is contained in:
bighuixiang
2025-06-26 00:37:07 +08:00
parent afa3b69f71
commit 2fcba962d1
16 changed files with 901 additions and 448 deletions

View File

@@ -5,6 +5,7 @@ import initAligningGuidelines, {
import { ThumbnailManager } from "./ThumbnailManager";
import { ExportManager } from "./ExportManager";
import {
findLayerRecursively,
isGroupLayer,
OperationType,
OperationTypes,
@@ -15,7 +16,11 @@ import { CanvasEventManager } from "./events/CanvasEventManager";
import CanvasConfig from "../config/canvasConfig";
import { RedGreenModeManager } from "./RedGreenModeManager";
import { EraserStateManager } from "./EraserStateManager";
import { deepClone, optimizeCanvasRendering } from "../utils/helper";
import {
deepClone,
generateId,
optimizeCanvasRendering,
} from "../utils/helper";
import { ChangeFixedImageCommand } from "../commands/ObjectLayerCommands";
import { isFunction } from "lodash-es";
import {
@@ -39,7 +44,9 @@ export class CanvasManager {
this.canvasHeight = options.canvasHeight || this.height; // 画布高度
this.canvasColor = options.canvasColor || "#ffffff"; // 画布背景颜色
this.enabledRedGreenMode = options.enabledRedGreenMode || false; // 是否启用红绿图模式
this.isFixedErasable = options.isFixedErasable || false; // 是否允许擦除固定图层
this.eraserStateManager = null; // 橡皮擦状态管理器引用
this.handleCanvasInit = null; // 画布初始化回调函数
// 初始化画布
this.initializeCanvas();
}
@@ -73,16 +80,50 @@ export class CanvasManager {
this.canvas.thumbnailManager = this.thumbnailManager; // 将缩略图管理器绑定到画布
// 设置画布辅助线
initAligningGuidelines(this.canvas);
// // 设置画布辅助线
// initAligningGuidelines(this.canvas);
// 设置画布中心线
initCenteringGuidelines(this.canvas);
// // 设置画布中心线
// initCenteringGuidelines(this.canvas);
// 初始化画布事件监听器
this._initCanvasEvents();
}
// 添加图像到指定图层
async addImageToLayer({ targetLayerId, fabricImage, ...options }) {
// 如果图层管理器存在,将图像合并到当前活动图层
if (this.layerManager) {
// 获取当前活动图层
let activeLayer = targetLayerId
? findLayerRecursively(this.layers.value, targetLayerId)?.layer
: this.layerManager.getActiveLayer();
if (activeLayer) {
// 确保新图像具有正确的图层信息
fabricImage.set({
layerId: activeLayer.id,
layerName: activeLayer.name,
id: fabricImage.id || generateId("brush_img_"),
});
// 执行高保真合并操作
await this.eventManager?.mergeLayerObjectsForPerformance?.({
fabricImage,
activeLayer,
options,
});
this.thumbnailManager?.generateLayerThumbnail(activeLayer.id);
// 返回true表示不要自动添加到画布因为我们已经通过图层管理器处理了
return true;
} else {
console.warn("没有活动图层,无法添加图像");
}
}
}
/**
* 初始化画布事件监听器
* 设置鼠标事件、键盘事件等
@@ -91,36 +132,7 @@ export class CanvasManager {
_initCanvasEvents() {
// 添加笔刷图像转换处理回调
this.canvas.onBrushImageConverted = async (fabricImage) => {
// 如果图层管理器存在,将图像合并到当前活动图层
if (this.layerManager) {
// 获取当前活动图层
const activeLayer = this.layerManager.getActiveLayer();
if (activeLayer) {
// 确保新图像具有正确的图层信息
fabricImage.set({
layerId: activeLayer.id,
layerName: activeLayer.name,
id:
fabricImage.id ||
`brush_img_${Date.now()}_${Math.floor(Math.random() * 1000)}`,
});
// 执行高保真合并操作
await this.eventManager?.mergeLayerObjectsForPerformance?.({
fabricImage,
activeLayer,
});
this.thumbnailManager?.generateLayerThumbnail(activeLayer.id);
// 返回true表示不要自动添加到画布因为我们已经通过图层管理器处理了
return true;
} else {
console.warn("没有活动图层,使用默认行为添加图像");
}
}
await this.addImageToLayer({ fabricImage, targetLayerId: null });
// 返回false表示使用默认行为直接添加到画布
return false;
};
@@ -155,6 +167,15 @@ export class CanvasManager {
this.thumbnailManager?.generateLayerThumbnail(
this.layerManager?.activeLayerId?.value
);
// 固定图层 的擦除也需要重新生成缩略图 要判断 当前固定图层是否锁定
const fixedLayer = this.layers?.value?.find(
(layer) => layer.isFixed && !layer.locked
);
// 如果有固定图层且未锁定,则生成缩略图
fixedLayer &&
this.isFixedErasable &&
this.thumbnailManager?.generateLayerThumbnail(fixedLayer?.id);
});
}
@@ -263,6 +284,10 @@ export class CanvasManager {
this.animationManager.setupInteractionAnimations();
}
setupCanvasInitEvent(handleCanvasInit) {
this.handleCanvasInit = handleCanvasInit;
}
setupLongPress(callback) {
if (this.eventManager) {
this.eventManager.setupLongPress(callback);
@@ -697,13 +722,26 @@ export class CanvasManager {
command.undoable =
options.undoable !== undefined ? options.undoable : false; // 默认不可撤销 undoable = true 为可撤销
return (
(await command?.execute?.()) || {
success: false,
layerId: null,
imageUrl: null,
const result = (await command?.execute?.()) || {
success: false,
layerId: null,
imageUrl: null,
};
const findLayer = this.layers.value.find((fItem) => {
if (options.targetLayerType === "fixed") {
return fItem.isFixed;
}
);
if (options.targetLayerType === "background") {
return fItem.isBackground;
}
return false;
});
// 如果找到了图层,则生成缩略图
findLayer && this.thumbnailManager?.generateLayerThumbnail(findLayer.id);
return result;
}
/**
@@ -934,7 +972,7 @@ export class CanvasManager {
}
// 清除当前画布内容
this.canvas.clear();
// this.canvas.clear(); // 清除画布内容 可以先去掉 这样加载闪动的情况就比较少 如果有问题 可以再打开
console.log("清除当前画布内容", canvasData);
delete canvasData.clipPath; // 删除当前裁剪路径
// 加载画布数据
@@ -1002,6 +1040,8 @@ export class CanvasManager {
}, 500);
console.log("画布JSON数据加载完成");
// 画布初始化事件
this.handleCanvasInit?.(ture);
resolve();
} catch (error) {
console.error("恢复图层数据失败:", error);