Update fabric.js Path points dynamically

前端 未结 4 788
栀梦
栀梦 2021-01-20 04:05

I\'m trying to add points to a path object dynamically. When I do, the path renders correctly, but the bounding rectangle never gets updated, making it nearly impossible for

相关标签:
4条回答
  • 2021-01-20 04:37

    I couldn't find any new way to do this. But I figured out something like below;

    1. create an SVG path string with modifications.
    2. create a new fabric path object.
    3. replace path, width, height and pathOffset properties of the original path object with the properties of the new path object.
    4. setCoords. renderAll etc...

    It may not be much efficient. But it was the solution for me.

        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();
    

    On my setup, it says path._parseDimensions is not a function. I didn't try to solve it. I have to change all path content. So my solution seems better for me :)

    0 讨论(0)
  • 2021-01-20 04:50

    Please, fabricjs does not support adding point dinamically as of now. To make it work you can add points like you are doing and then use internal method path._parseDimensions() each time you add points and desire to update bounding box dimension.

    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();
    

    Look this updated fiddle that has the necessary code to solve your problem. I hope it works for every situation.

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

    0 讨论(0)
  • 2021-01-20 04:56

    It ended up being more complicated. If a point is added to the path that results in _parseDimensions returning a left value that is negative, the path would jump around the screen. For my use case, I need the path to stay in place while points are added and manipulated. This fiddle shows my working solution:

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

    If you run it with a JS console open, you will see the script pausing after each additional point is added, or current point is manipulated. As this happens you will see that the path does not get moved along the canvas, which is the desired behavior. After all the break points complete, you will see that the curve is centered within its selection box.

    If there is an easier way to achieve this behavior, I would love to know.

    Here's the function I'm using to set the dimensions just in case the fiddle link ever goes away:

    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();
    }
    
    0 讨论(0)
  • 2021-01-20 05:03

    In fabric 3.3.2 I solved it combining the answers above:

    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()
    

    This correctly updates my path bounding box after adding points like:

    path.set({path: points})
    

    I am not sure though, if this works with negative top and left values, but I didn't need that in my case. I guess the main thing is that the _parseDimensions() method was renamed to _calcDimensions().

    0 讨论(0)
提交回复
热议问题