207 lines
5.0 KiB
TypeScript
207 lines
5.0 KiB
TypeScript
import { ref } from 'vue'
|
||
import { OperationType } from '../tools/layerHelper'
|
||
import { BrushManager } from "./brushes/brushManager";
|
||
import { BrushIndicator } from "./BrushIndicator";
|
||
import i18n from "@/lang";
|
||
const t = i18n.global.t
|
||
export class ToolManager {
|
||
stateManager: any
|
||
canvasManager: any
|
||
currentTool: any
|
||
brushManager: any
|
||
tools: any[]
|
||
brushIndicator: any
|
||
constructor(options) {
|
||
this.stateManager = options.stateManager;
|
||
this.canvasManager = options.canvasManager;
|
||
this.currentTool = ref(null)
|
||
|
||
this.tools = [
|
||
/** 选择工具 */
|
||
{
|
||
name: OperationType.SELECT,
|
||
cursor: "default",
|
||
setup: this.setupSelectTool.bind(this),
|
||
selection: true,
|
||
},
|
||
/** 移动工具 */
|
||
{
|
||
name: OperationType.PAN,
|
||
cursor: "grab",
|
||
setup: this.setupMoveTool.bind(this),
|
||
},
|
||
/** 画笔工具 */
|
||
{
|
||
name: OperationType.DRAW,
|
||
cursor: "crosshair",
|
||
setup: this.setupBrushTool.bind(this),
|
||
isDrawingMode: true,
|
||
},
|
||
/** 橡皮擦工具 */
|
||
{
|
||
name: OperationType.ERASER,
|
||
cursor: "crosshair",
|
||
setup: this.setupEraserTool.bind(this),
|
||
isDrawingMode: true,
|
||
},
|
||
/** 智能选框工具 */
|
||
{
|
||
name: OperationType.SELECTBOX,
|
||
cursor: "crosshair",
|
||
},
|
||
/** 矩形工具 */
|
||
{
|
||
name: OperationType.RECTANGLE,
|
||
cursor: "crosshair",
|
||
},
|
||
/** 直线工具 */
|
||
{
|
||
name: OperationType.LINE,
|
||
cursor: "crosshair",
|
||
},
|
||
/** 箭头工具 */
|
||
{
|
||
name: OperationType.ARROW,
|
||
cursor: "crosshair",
|
||
},
|
||
/** 椭圆工具 */
|
||
{
|
||
name: OperationType.ELLIPSE,
|
||
cursor: "crosshair",
|
||
},
|
||
/** 三角形工具 */
|
||
{
|
||
name: OperationType.TRIANGLE,
|
||
cursor: "crosshair",
|
||
},
|
||
/** 五角星工具 */
|
||
{
|
||
name: OperationType.STAR,
|
||
cursor: "crosshair",
|
||
},
|
||
|
||
]
|
||
}
|
||
onMounted() {
|
||
this.brushIndicator = new BrushIndicator(this.canvasManager.canvas, {
|
||
strokeColor: "rgba(0, 0, 0, 0.6)",
|
||
strokeWidth: 1,
|
||
fillColor: "rgba(0, 0, 0, 0.1)",
|
||
});
|
||
this.brushManager = new BrushManager({
|
||
canvas: this.canvasManager.canvas,
|
||
layerManager: this.canvasManager.layerManager, // 传入图层管理器引用
|
||
brushIndicator: this.brushIndicator,
|
||
t,
|
||
});
|
||
this.stateManager.setManager({
|
||
brushManager: this.brushManager,
|
||
})
|
||
}
|
||
setTool(value: string) {
|
||
const tool = this.tools.find((t) => t.name === value)
|
||
if (!tool) return console.warn(`工具${tool}不存在`)
|
||
this.currentTool.value = tool.name
|
||
this.canvasManager.canvas.defaultCursor = tool.cursor
|
||
this.setCanvasEvented(!!tool.selection)
|
||
this.canvasManager.canvas.isDrawingMode = !!tool.isDrawingMode;// 绘制模式
|
||
if (!tool.isDrawingMode) this._disableBrushIndicator()// 非绘制模式,禁用笔刷指示器
|
||
|
||
|
||
if (tool.setup) tool.setup()
|
||
|
||
setTimeout(() => {
|
||
this.canvasManager.renderAll()
|
||
});
|
||
}
|
||
// 切换工具时,设置画布事件
|
||
setCanvasEvented(value: boolean) {
|
||
this.canvasManager.canvas.selection = value
|
||
this.canvasManager.canvas.getObjects().forEach((v) => {
|
||
if (v.info?.lock) return
|
||
v.evented = value
|
||
})
|
||
}
|
||
/** 选择工具 */
|
||
setupSelectTool() {
|
||
}
|
||
/** 移动工具 */
|
||
setupMoveTool() {
|
||
}
|
||
/** 画笔工具 */
|
||
setupBrushTool() {
|
||
if (!this.canvasManager.canvas) return;
|
||
|
||
// 确保有笔刷管理器
|
||
if (this.brushManager) {
|
||
// 检查画笔是否正在更新中
|
||
if (this.brushManager.isUpdatingBrush) {
|
||
console.warn("画笔正在更新中,请稍候...");
|
||
return;
|
||
}
|
||
const brushStore = this.brushManager?.brushStore
|
||
if (brushStore) {
|
||
// 同步基本属性
|
||
this.brushManager.setBrushSize(brushStore.state.size);
|
||
this.brushManager.setBrushColor(brushStore.state.color);
|
||
this.brushManager.setBrushOpacity(brushStore.state.opacity);
|
||
|
||
// 同步笔刷类型 - 修复方法名,使用正确的setBrushType方法
|
||
this.brushManager.setBrushType("pencil");
|
||
}
|
||
|
||
// 更新应用到画布
|
||
this.brushManager.updateBrush();
|
||
}
|
||
|
||
// 启用笔刷指示器并同步颜色
|
||
this._enableBrushIndicator();
|
||
}
|
||
/**
|
||
* 设置橡皮擦工具
|
||
*/
|
||
setupEraserTool() {
|
||
if (!this.canvasManager.canvas) return;
|
||
|
||
// 确保有笔刷管理器
|
||
if (this.brushManager) {
|
||
this.brushManager.createEraser();
|
||
}
|
||
|
||
this.stateManager.layerManager.setActiveObjectErasable()
|
||
// 启用笔刷指示器
|
||
this._enableBrushIndicator();
|
||
}
|
||
|
||
/**
|
||
* 启用笔刷指示器
|
||
* @param {String} color 笔刷颜色(可选)
|
||
* @private
|
||
*/
|
||
_enableBrushIndicator(color?: string) {
|
||
if (!this.brushIndicator) return;
|
||
|
||
// 获取当前笔刷大小
|
||
const brushSize = this.brushManager?.getBrushSize() || 5;
|
||
// 获取当前笔刷颜色
|
||
const brushColor = color || this.brushManager?.getBrushColor() || "#000000";
|
||
|
||
// 启用指示器
|
||
this.brushIndicator.enable(brushSize);
|
||
this.brushIndicator.updateSize(brushSize);
|
||
// 更新指示器颜色
|
||
this.brushIndicator.updateColor(brushColor);
|
||
}
|
||
|
||
/** 禁用笔刷指示器 */
|
||
_disableBrushIndicator() {
|
||
if (!this.brushIndicator) return;
|
||
|
||
this.brushIndicator.disable();
|
||
}
|
||
dispose() {
|
||
this.brushIndicator?.dispose()
|
||
this.brushManager?.dispose()
|
||
}
|
||
}
|