Angular中使用Fabric.js绘制矩形遇selection:created事件未触发求助
问题分析与修复方案
核心问题总结
selection:created事件无法触发的根本原因是绘制模式的逻辑判断完全颠倒,导致绘制状态和选择状态的逻辑冲突- 代码中存在多处逻辑错误(如鼠标事件条件反转、错误修改画布尺寸、重复添加元素等),进一步干扰了Fabric.js的原生事件机制
修正后的完整代码
let can = new fabric.Canvas('fabricCanvas_' + page._pageIndex); this.initCanvas_rect(can); initCanvas_rect(canvas: any) { let isDown = false; let startPosition: { x: number; y: number }; let rect: fabric.Rect; let drawingMode = true; // 默认处于绘制模式 // 鼠标按下:开始绘制矩形 canvas.on('mouse:down', (options: any) => { if (drawingMode) { // 修正:绘制模式下才触发绘制逻辑 isDown = true; startPosition = canvas.getPointer(options.e); rect = new fabric.Rect({ left: startPosition.x, top: startPosition.y, width: 0, height: 0, stroke: 'red', strokeWidth: 3, fill: '', selectable: true // 确保绘制后的矩形可被选中 }); canvas.add(rect); } }); // 鼠标抬起:结束绘制 canvas.on('mouse:up', () => { isDown = false; // 移除重复添加rect的代码,mouse:down时已添加 }); // 鼠标移动:更新矩形尺寸 canvas.on('mouse:move', (options: any) => { if (isDown && drawingMode) { // 修正:仅在绘制模式且鼠标按下时更新 const endPosition = canvas.getPointer(options.e); // 计算矩形的真实位置和尺寸(处理从右下往左上绘制的情况) const left = Math.min(startPosition.x, endPosition.x); const top = Math.min(startPosition.y, endPosition.y); const width = Math.abs(endPosition.x - startPosition.x); const height = Math.abs(endPosition.y - startPosition.y); // 更新rect属性,而非修改画布尺寸 rect.set({ left, top, width, height }); canvas.renderAll(); } }); // 选中元素时关闭绘制模式 canvas.on('selection:created', () => { drawingMode = false; }); // 取消选中时恢复绘制模式 canvas.on('selection:cleared', () => { drawingMode = true; }); }
关键修改说明
- 修正
mouse:down的判断条件:将!drawingMode改为drawingMode,确保只有在绘制模式下才创建矩形 - 修复
mouse:move的逻辑:- 条件改为
isDown && drawingMode,避免非绘制状态下执行无效逻辑 - 移除错误的
canvas.setWidth/setHeight调用,改为直接更新矩形的left/top/width/height属性 - 处理反向绘制(从右下到左上)的情况,确保矩形位置正确
- 条件改为
- 删除
mouse:up中重复添加rect的代码,避免元素重复添加 - 给绘制的矩形添加
selectable: true属性,确保可以被选中,从而触发selection:created事件 - 变量声明使用
let替代var,提升代码块级作用域的安全性
内容的提问来源于stack exchange,提问作者meth
相关产品推荐
相关产品推荐

