更新fabric.js动态路径点

时间:2015-03-12 13:54:17

标签: javascript svg fabricjs

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

正如您在下面的代码中所看到的,路径最初是使用单个点创建的,然后我动态添加第二个点以及一个控制点。执行此操作后,边界矩形永远不会更新:

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/

4 个答案:

答案 0 :(得分:3)

请到目前为止,fabricjs不支持dinamically添加点。 要使其工作,您可以添加像您正在做的点,然后在每次添加点时使用内部方法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/

答案 1 :(得分: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();
}

答案 2 :(得分:0)

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

  1. 创建具有修改的SVG路径字符串。
  2. 创建一个新的结构路径对象。
  3. 用新路径对象的属性替换原始路径对象的路径,宽度,高度和pathOffset属性。
  4. setCoords。 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不是函数 。 我没有尝试解决它。我必须更改所有路径内容。所以我的解决方案对我来说似乎更好:)

答案 3 :(得分:0)

在结构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})

但是,我不确定这是否适用于负的top和left值,但是在我的情况下不需要。我猜最主要的是_parseDimensions()方法已重命名为_calcDimensions()