You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 19:45:33