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 a user to select and move the path on canvas.
As you can see in the code below, the path is initially created with a single point, then I dynamically add a second point as well as a control point. After doing this, the bounding rectangle never updates:
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();
I also tried calling path.setCoords()
, but that did not make any difference. How can I get the bounding rectangle to update its dimensions after adding points to a path?
Here's a fiddle: http://jsfiddle.net/flyingL123/17ueLva2/2/
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/
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();
}