Files
aida_front/src/component/Canvas/CanvasEditor/managers/PartManager.js

326 lines
8.4 KiB
JavaScript
Raw Normal View History

2026-01-14 14:43:43 +08:00
import { fabric } from "fabric-with-all";
import { generateId } from "../utils/helper";
import { OperationType } from "../utils/layerHelper";
import { CreateSelectionCommand } from "../commands/SelectionCommands";
import { ClearSelectionCommand } from "../commands/LassoCutoutCommand";
2026-01-15 13:42:33 +08:00
import addIcon from "@/assets/images/canvas/add.png";
import removeIcon from "@/assets/images/canvas/remove.png";
2026-01-15 17:15:05 +08:00
import { Https } from "@/tool/https";
import store from "@/store";
2026-01-14 14:43:43 +08:00
/**
* 部件选择管理器
*/
export class PartManager {
2026-01-15 13:42:33 +08:00
/**
* 创建部件选择管理器
* @param {Object} options 配置选项
* @param {Object} options.canvas fabric.js画布实例
* @param {Object} options.commandManager 命令管理器实例
* @param {Object} options.canvasManager 画布管理实例
* @param {Object} options.layerManager 图层管理实例
* @param {Object} options.toolManager 工具管理实例
*/
constructor(options = {}) {
this.canvas = options.canvas;
this.commandManager = options.commandManager;
this.layerManager = options.layerManager;
this.canvasManager = options.canvasManager;
this.toolManager = options.toolManager;
2026-01-15 17:15:05 +08:00
this.props = options.props;
2026-01-15 13:42:33 +08:00
// 状态
this.isActive = false;
this.partObject = null; // 当前选区对象
this.partId = "part_selector";
this.defaultCursor = "default";
// 绘制状态
this.drawingObject = null;
this.startPoint = null;
this.partPath = null; // 存储选区路径数据
// 不再直接绑定事件处理函数
this._mouseDownHandler = null;
this._mouseMoveHandler = null;
this._mouseUpHandler = null;
this._keyDownHandler = null;
// 选区相关的工具类型
this.tools = [
OperationType.PART,
OperationType.PART_RECTANGLE,
OperationType.PART_BRUSH,
OperationType.PART_ERASER,
];
// 当前工具
this.activeTool = this.toolManager.activeTool;
// 选区状态变化回调
this.onSelectionChanged = null;
}
/**
* 设置当前工具
* @param {String} toolId 工具ID
*/
setCurrentTool(toolId) {
// 检查是否为选区工具
const wasActive = this.isActive;
this.isActive = this.tools.includes(toolId);
// 如果从非选区工具切换到选区工具,初始化事件
if (!wasActive && this.isActive) {
this.initEvents();
}
// 如果从选区工具切换到非选区工具,清理事件和选区
else if (wasActive && !this.isActive) {
this.cleanupEvents();
this.clearSelection();
}
}
/**
* 初始化选区相关事件
*/
initEvents() {
if (!this.canvas || this._mouseDownHandler) return; // 避免重复初始化
this.defaultCursor = this.canvas.defaultCursor;
// 保存实例引用,用于事件处理函数中
const self = this;
// 鼠标按下事件处理
this._mouseDownHandler = (options) => {
// 如果选区功能未激活,不处理事件
if (!this.isActive) return;
// 阻止事件冒泡,避免与 CanvasEventManager 冲突
options.e.stopPropagation();
switch (this.activeTool.value) {
case OperationType.PART:
this._pointDownkHandler(options);
break;
case OperationType.PART_RECTANGLE:
this._rectangleDownHandler(options);
break;
case OperationType.PART_BRUSH:
this._brushDownHandler(options);
break;
case OperationType.PART_ERASER:
this._eraseDownHandler(options);
break;
default:
break;
}
};
// 鼠标移动事件处理
this._mouseMoveHandler = (options) => {
// 如果选区功能未激活或没有正在绘制的对象,不处理事件
if (!this.isActive) return;
// 阻止事件冒泡
options.e.stopPropagation();
switch (this.activeTool.value) {
case OperationType.PART:
this._pointMoveHandler(options);
break;
case OperationType.PART_RECTANGLE:
this._rectangleMoveHandler(options);
break;
case OperationType.PART_BRUSH:
this._brushMoveHandler(options);
break;
case OperationType.PART_ERASER:
this._eraseMoveHandler(options);
break;
default:
break;
}
};
// 鼠标抬起事件处理
this._mouseUpHandler = (options) => {
// 如果选区功能未激活或没有正在绘制的对象,不处理事件
if (!this.isActive) return;
// 阻止事件冒泡
if (options && options.e) {
options.e.stopPropagation();
}
switch (this.activeTool.value) {
case OperationType.PART:
this._pointUpHandler(options);
break;
case OperationType.PART_RECTANGLE:
this._rectangleUpHandler(options);
break;
case OperationType.PART_BRUSH:
this._brushUpHandler(options);
break;
case OperationType.PART_ERASER:
this._eraseUpHandler(options);
break;
default:
break;
}
};
// 键盘事件处理
this._keyDownHandler = (event) => {
// 只在选区功能激活时处理键盘事件
if (!this.isActive) return;
};
// 添加事件监听
this.canvas.on("mouse:down", this._mouseDownHandler);
this.canvas.on("mouse:move", this._mouseMoveHandler);
this.canvas.on("mouse:up", this._mouseUpHandler);
// 添加键盘事件监听
document.addEventListener("keydown", this._keyDownHandler);
}
/**
* 清理事件监听
*/
cleanupEvents() {
if (!this.canvas) return;
// 移除事件监听
if (this._mouseDownHandler) {
this.canvas.off("mouse:down", this._mouseDownHandler);
this._mouseDownHandler = null;
}
if (this._mouseMoveHandler) {
this.canvas.off("mouse:move", this._mouseMoveHandler);
this._mouseMoveHandler = null;
}
if (this._mouseUpHandler) {
this.canvas.off("mouse:up", this._mouseUpHandler);
this._mouseUpHandler = null;
}
if (this._keyDownHandler) {
document.removeEventListener("keydown", this._keyDownHandler);
this._keyDownHandler = null;
}
}
// 点选工具模式下点击事件处理
_pointDownkHandler(options) {
const button = options.button;
const isLeft = button === 1;// 左键1添加 右键3删除
const icon = `url("${isLeft ? addIcon : removeIcon}") 16 16, default`
this.canvas.upperCanvasEl.style.cursor = icon;
}
// 点选工具模式下移动事件处理
2026-01-15 17:15:05 +08:00
_pointMoveHandler(options) { }
2026-01-15 13:42:33 +08:00
// 点选工具模式下抬起事件处理
_pointUpHandler(options) {
const button = options.button;
const isLeft = button === 1;// 左键1添加 右键3删除
this.canvas.upperCanvasEl.style.cursor = this.defaultCursor;
2026-01-15 17:15:05 +08:00
const fixedObject = this.canvasManager.getFixedLayerObject();
if (!fixedObject) return console.warn("未找到固定图层");
2026-01-15 13:42:33 +08:00
const { x, y } = options.pointer;
2026-01-15 17:15:05 +08:00
const width = fixedObject.width * fixedObject.scaleX;
const height = fixedObject.height * fixedObject.scaleY;
const X = x - (fixedObject.left - width / 2);
const Y = y - (fixedObject.top - height / 2);
this.getSegAnythingImage({
image_path: "aida-users/24299/sketch/70bb39cc-63e0-44a9-a627-3542d0f9cd70.png",
type: "point",
points: [[X, Y], [X - 10, Y - 10]],
labels: [1, 0],
});
2026-01-15 13:42:33 +08:00
}
// 框选工具模式下点击事件处理
_rectangleDownHandler(options) {
}
// 框选工具模式下移动事件处理
_rectangleMoveHandler(options) {
}
// 框选工具模式下抬起事件处理
_rectangleUpHandler(options) {
}
// 绘制工具模式下点击事件处理
_brushDownHandler(options) {
}
// 绘制工具模式下移动事件处理
_brushMoveHandler(options) {
}
// 绘制工具模式下抬起事件处理
_brushUpHandler(options) {
}
// 擦除工具模式下抬起事件处理
_eraseUpHandler(options) {
}
// 擦除工具模式下点击事件处理
_eraseDownHandler(options) {
}
// 擦除工具模式下移动事件处理
_eraseMoveHandler(options) {
}
2026-01-15 17:15:05 +08:00
// 获取分隔后图片
async getSegAnythingImage(obj) {
const user_id = store.state.UserHabit.userDetail.userId;
const data = {
user_id,
...obj,
}
Https.axiosPost(Https.httpUrls.segAnything, data)
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
}
2026-01-15 13:42:33 +08:00
/**
* 清除选区
*/
clearSelection() {
// 移除选区对象
// this.removeSelectionFromCanvas();
// 重置选区状态
this.partObject = null;
this.partPath = null;
// 触发选区变化回调
if (this.onSelectionChanged && typeof this.onSelectionChanged === "function") {
this.onSelectionChanged();
}
return true;
}
/**
* 清理资源
*/
dispose() {
this.cleanupEvents();
this.clearSelection();
this.canvas = null;
this.commandManager = null;
this.layerManager = null;
}
2026-01-14 14:43:43 +08:00
}