FabricJS 4.5.0实现右键结束铅笔工具SVG路径绘制的方法
解决Fabric JS铅笔工具右键结束绘制的方案
1. 阻止画布右键默认菜单
先给画布绑定事件,阻止右键时弹出系统菜单,同时触发绘图结束逻辑:
// 监听画布鼠标按下事件,处理右键逻辑 canvas.on('mouse:down', function(e) { if (e.e.button === 2) { e.e.preventDefault(); if (canvas.isDrawingMode && tool.toString().toLowerCase() === 'pencil') { endPencilDrawing(); } } }); // 直接给canvas元素绑定contextmenu事件,增强兼容性 canvas.getElement().addEventListener('contextmenu', function(e) { if (canvas.isDrawingMode && tool.toString().toLowerCase() === 'pencil') { e.preventDefault(); } });
2. 自定义绘图结束逻辑
创建endPencilDrawing函数,负责关闭绘图模式、将临时路径转为画布正式对象,并导出SVG:
function endPencilDrawing() { canvas.isDrawingMode = false; // 获取铅笔工具绘制的临时路径 const tempPath = canvas.freeDrawingBrush.getPath(); if (tempPath && tempPath.length > 0) { // 生成Fabric路径对象 const formalPath = new fabric.Path(tempPath, { stroke: canvas.freeDrawingBrush.color, strokeWidth: canvas.freeDrawingBrush.width, strokeLineCap: canvas.freeDrawingBrush.strokeLineCap, strokeLineJoin: canvas.freeDrawingBrush.strokeLineJoin, strokeMiterLimit: canvas.freeDrawingBrush.strokeMiterLimit, fill: '' }); // 添加到画布 canvas.add(formalPath); // 导出路径为SVG(可自行存储或上传) const pathSVG = formalPath.toSVG(); console.log('当前路径SVG:', pathSVG); // 恢复对象选择功能 changeObjectSelection(true); } }
3. 修复左键重复点击路径消失问题
原逻辑直接开启isDrawingMode会触发Fabric默认的路径重置,需要手动控制绘图状态:
let isPencilDrawing = false; if (tool.toString().toLowerCase() === 'pencil') { changeObjectSelection(false); // 初始化铅笔工具,避免重复创建 if (!canvas.freeDrawingBrush || !(canvas.freeDrawingBrush instanceof fabric.PencilBrush)) { canvas.freeDrawingBrush = new fabric.PencilBrush(canvas); } // 更新画笔属性 canvas.freeDrawingBrush.strokeLineCap = $('#brushStrokeCap').val(); canvas.freeDrawingBrush.strokeLineJoin = $('#brushStrokeLineJoin').val(); canvas.freeDrawingBrush.strokeMiterLimit = $('#brushMiter').val(); canvas.freeDrawingBrush.width = 1; canvas.freeDrawingBrush.color = strokePickr.getColor().toRGBA().toString(); // 监听左键开始/结束绘图 canvas.on('mouse:down', function(e) { if (e.e.button === 0 && !isPencilDrawing) { canvas.isDrawingMode = true; isPencilDrawing = true; } }); canvas.on('mouse:up', function(e) { if (e.e.button === 0 && isPencilDrawing) { endPencilDrawing(); isPencilDrawing = false; } }); }
4. 工具切换时清理事件监听(可选)
切换到其他工具时,移除铅笔相关的事件监听,避免逻辑冲突:
function switchTool(newTool) { if (tool.toString().toLowerCase() === 'pencil') { canvas.off('mouse:down'); canvas.off('mouse:up'); isPencilDrawing = false; canvas.isDrawingMode = false; } // 其他工具切换逻辑... tool = newTool; }
修改后可实现:
- 右键点击画布会阻止系统菜单,同时结束铅笔绘制并生成正式路径
- 左键点击开始绘图,松开左键结束绘图,不会出现重复点击路径消失的问题
- 绘制的路径会作为正式对象保留在画布上,同时可导出SVG格式
内容的提问来源于stack exchange,提问作者techi
相关产品推荐
相关产品推荐

