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

Fabric.js中自动生成SVG对象出现边缘模糊、运行卡顿问题求解

问题根源分析

你的实现方案存在核心逻辑错误:你将菜单项对象的创建、添加到画布的逻辑写在了mouse:move事件回调中,该事件每移动1像素就会触发一次,每触发一次就会往画布新增2个路径对象,运行时间稍长画布上会堆叠成千上万的重复对象,这是两个问题的共同诱因。

  • 边缘模糊失真:大量相同路径对象在同一位置堆叠,每个对象的描边自带抗锯齿效果,多层半透明抗锯齿边缘叠加后就会出现模糊、发虚的失真问题,和边框粗细、透明度参数无关。
  • 运行卡顿:画布对象数量随鼠标移动指数级增长,fabric.js每次渲染都要遍历所有对象计算绘制参数,渲染压力随对象数量暴涨急剧升高,自然会出现卡顿,哪怕仅接入少量菜单项,只要在mouse:move中反复新增对象,很快就会达到卡顿阈值。
解决方案
  1. 首先将菜单项的创建逻辑从mouse:move事件中移出,仅在初始化时创建一次菜单项,放置到画布固定的菜单区域,设置为可拖拽即可,不需要每次鼠标移动都重新创建。
  2. 如果你的需求是「拖动菜单项时复制出一个新对象放置到画布任意位置」,可以监听mouse:down事件判断点击的是否为菜单项,只有拖拽菜单项时才创建一个副本跟随鼠标,拖拽结束后将副本固定到目标位置,原有菜单项保留在菜单区域不动。
  3. 额外性能优化建议:
    • 静态对象可以设置selectable: false,完全不需要交互的对象还可以设置evented: false,减少fabric.js的事件计算开销
    • 不需要修改的多个静态对象可以合并为fabric.Group,减少渲染遍历的开销
    • 你当前使用的fabric.js 1.5.0版本非常老旧,建议升级到最新稳定版,新版本对渲染性能、路径绘制效果都有大量优化

以下是修正后的代码示例:

var canvas = this.__canvas = new fabric.Canvas('c');

// 初始化时仅创建一次菜单项
function createMenuItems() {
  var prthss = new fabric.Path('m 37.066323,664.72823 c -0.526572,-7.80009 -0.530124,-15.64425 -0.0136,-23.48118 5.487368,-4.37172 13.310902,-4.34082 18.754907,0.0798 -0.533656,7.62909 -0.579648,15.59958 0.03127,23.20784 -5.375259,4.48954 -13.24684,4.55212 -18.772561,0.19357 z');
  prthss.set({
    fill: '#fff', 
    stroke: '#1a1a1a', 
    strokeWidth: 2, 
    opacity: 1, 
    left:130, 
    top:110, 
    lockScalingX: true, 
    lockScalingY: true, 
    originX: 'center',  
    originY: 'center',
    isMenuItem: true // 自定义标记区分菜单项和普通对象
  });
  prthss.setControlsVisibility({ mt: false, mb: false, ml: false, mr: false, bl: false, br: false, tl: false, tr: false, mtr: true });
  canvas.add(prthss);

  var tpr = new fabric.Path('m 313.13828,618.74455 c 2.11345,1.08854 2.18323,3.22159 2.1986,5.06456 m -23.10338,-9.61297 7.80969,0 -4.00165,0 0.0394,9.61297 m 5.78092,0 0.0394,-9.61297 2.83155,0 c 3.28759,0 3.40318,4.60019 0,4.60019 l -2.91027,0 m 8.34298,5.01278 0.0394,-9.61297 2.83154,0 c 3.2876,0 3.40319,4.60019 0,4.60019 l -2.91026,0 m 9.56121,-0.23614 c 0,8.35908 -6.77638,15.13546 -15.13545,15.13546 -8.35909,0 -15.13547,-6.77637 -15.13547,-15.13546 0,-8.35908 6.77638,-15.13544 15.13547,-15.13544 8.35907,0 15.13545,6.77638 15.13545,15.13544 z');
  tpr.set({
    fill: '#fff', 
    stroke: '#1a1a1a', 
    strokeWidth: 2, 
    opacity: 1, 
    left:100, 
    top:110, 
    lockRotation: true, 
    originX: 'center',  
    originY: 'center',
    isMenuItem: true
  });
  canvas.add(tpr);
}

// 初始化执行一次
createMenuItems();

// 拖拽复制菜单项逻辑
let cloneObj = null;
canvas.on('mouse:down', function(e) {
  if (e.target && e.target.isMenuItem) {
    // 点击菜单项时创建副本
    e.target.clone(function(cloned) {
      cloneObj = cloned;
      cloneObj.set({
        left: e.pointer.x,
        top: e.pointer.y,
        isMenuItem: false
      });
      canvas.add(cloneObj);
    });
  }
});

canvas.on('mouse:move', function(e) {
  if (cloneObj) {
    // 仅存在拖拽副本时更新位置,不新增对象
    cloneObj.set({
      left: e.pointer.x,
      top: e.pointer.y
    });
    canvas.renderAll();
  }
});

canvas.on('mouse:up', function() {
  cloneObj = null; // 拖拽结束清空标记
});
.controls {
    display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js" type="text/javascript"></script>

<h3>Menu with autogenerative items </h3>

<canvas id="c" width="400" height="300" style="border:1px solid #ccc"></canvas>

内容的提问来源于stack exchange,提问作者SIMBIOSIS surl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 05:39:02