【问题标题】:Update fabric.js Path points dynamically动态更新 fabric.js 路径点
【发布时间】:2015-05-14 17:22:45
【问题描述】:

我正在尝试动态地将点添加到路径对象。当我这样做时,路径会正确呈现,但边界矩形永远不会更新,这使得用户几乎不可能在画布上选择和移动路径。

正如您在下面的代码中看到的,路径最初是用一个点创建的,然后我动态添加了第二个点和一个控制点。这样做之后,边界矩形永远不会更新:

var canvas = new fabric.Canvas('c');
canvas.backgroundColor = '#f5f5f5';
var path = new fabric.Path('M 0 20',{
    left: 100,
    top: 100,
    stroke: 'black',
    fill: ''
});

canvas.add(path);

var commandArray = [];
commandArray[0] = 'Q';
commandArray[1] = 50;
commandArray[2] = 100;
commandArray[3] = 100;
commandArray[4] = 20;

path.path[1] = commandArray;

canvas.renderAll();

我也试过打电话给path.setCoords(),但这并没有什么不同。向路径添加点后,如何让边界矩形更新其尺寸?

这是一个小提琴:http://jsfiddle.net/flyingL123/17ueLva2/2/

【问题讨论】:

    标签: javascript svg fabricjs


    【解决方案1】:

    在 fabric 3.3.2 中,我结合上面的答案解决了它:

    var dims = path._calcDimensions()
    path.set({
      width: dims.width,
      height: dims.height,
      left: dims.left,
      top: dims.top,
      pathOffset: {
        x: dims.width / 2 + dims.left,
        y: dims.height / 2 + dims.top
      },
      dirty: true
    })
    path.setCoords()
    

    这会在添加点后正确更新我的路径边界框:

    path.set({path: points})
    

    但我不确定这是否适用于负顶部和左侧值,但在我的情况下我不需要它。我猜主要是_parseDimensions()方法被重命名为_calcDimensions()

    【讨论】:

    • 也许这将是现在最好的答案,因为fabricjs已更新
    【解决方案2】:

    目前,fabricjs 不支持动态添加点。 为了使其工作,您可以像现在一样添加点,然后在每次添加点并希望更新边界框尺寸时使用内部方法path._parseDimensions()

    var dims = path._parseDimensions();
    path.setWidth(dims.width);
    path.setHeight(dims.height);
    path.pathOffset.x = path.width/2;
    path.pathOffset.y = path.height/2;
    path.setCoords();
    

    看看这个更新的小提琴,它有必要的代码来解决你的问题。 我希望它适用于所有情况。

    http://jsfiddle.net/17ueLva2/6/

    【讨论】:

      【解决方案3】:

      它最终变得更加复杂。如果将一个点添加到导致_parseDimensions 返回负数left 值的路径,则路径将在屏幕上跳跃。对于我的用例,我需要在添加和操作点时保持路径不变。这个小提琴显示了我的工作解决方案:

      http://jsfiddle.net/flyingL123/8763bx2q/8/

      如果您在打开 JS 控制台的情况下运行它,您将看到脚本在添加每个附加点或当前点被操作后暂停。发生这种情况时,您将看到路径不会沿着画布移动,这是所需的行为。在所有断点完成后,您将看到曲线在其选择框内居中。

      如果有更简单的方法来实现这种行为,我很想知道。

      这是我用来设置尺寸的函数,以防小提琴链接消失:

      function updateDims() {
          var dims = path._parseDimensions(),
              prevDims = path.prevDims || {},
              leftDiff = dims.left - (prevDims.left || 0),
              topDiff = dims.top - (prevDims.top || 0);
      
          path.setWidth(dims.width);
          path.setHeight(dims.height);
      
          if (dims.left < 0) {
              path.pathOffset.x = path.width/2 + dims.left;
              path.left = path.left + leftDiff;
          } else {
              path.pathOffset.x = path.width/2;
          }
      
          if (dims.top < 0) {
              path.pathOffset.y = path.height/2 + dims.top;
              path.top = path.top + topDiff;
          } else {
               path.pathOffset.y = path.height/2;   
          }
      
          path.prevDims = dims;
          path.setCoords();
      }
      

      【讨论】:

      • 如何为fabric.Polygon 做到这一点,我有同样的问题,但我使用polygon 而不是path @flyingL123
      • 尝试做同样的事情,但在我的情况下,路径永远不会被添加到画布中。这是代码,请帮助`function initializePath(pointsArray) { var path = new fabric.Path('M 0 0'); path.path[0] = pointsArray; path.set(选项); canvas.add(路径); } 函数 addPath(pointsArray) { latestAddedPath.path.push(pointsArray); canvas.renderAll(); }`
      【解决方案4】:

      我找不到任何新的方法来做到这一点。但我想出了类似下面的东西;

      1. 创建带有修改的 SVG 路径字符串。
      2. 创建一个新的结构路径对象。
      3. 将原始路径对象的路径、宽度、高度和 pathOffset 属性替换为新路径对象的属性。
      4. 设置坐标。 renderAll 等...

      它可能效率不高。但这对我来说是解决方案。

          var pathObject = new fabric.Path("M0,0 L100,100 ~ Z");
      
          var updatedPath =  new fabric.Path("M50,100 L120,46 ~ Z");
      
          pathObject.set({
            path : updatedPath.path,
            width : updatedPath.width,
            height : updatedPath.height,
            pathOffset: updatedPath.pathOffset
          });
          pathObject.setCoords();
      

      在我的设置中,它说 path._parseDimensions 不是函数。 我没有试图解决它。我必须更改所有路径内容。所以我的解决方案对我来说似乎更好:)

      【讨论】:

      • 感谢分享@kadir_ilkimen。如果您想分享一个您知道有效的示例,用户会发现它更有用。
      • 您可以使用edit链接来编辑您的帖子,而不是删除答案并再次发布
      【解决方案5】:

      Fabric 4.6.0

      如果你看一下 Path 的构造函数,它会调用

      fabric.Polyline.prototype._setPositionDimensions.call(this, options);
      

      最后。其中this 是您的路径,options 是您的路径构造函数的第二个参数。在每次路径添加/删除时调用上面的方法来更新位置和边界就足够了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 2020-09-24
        • 2015-03-17
        • 2012-08-04
        • 1970-01-01
        • 2018-12-26
        相关资源
        最近更新 更多