DenEwout
DenEwout

Reputation: 944

How does fabric.Group positioning work?

I'm working on a project that requires groups of objects. I want to add something to a group after the group has already been drawn on the canvas. I put the gist of what I want to accomplish in the following jsfiddle: http://jsfiddle.net/85x3hzx7/2/

First off, I draw a grid in order to help visualize the position. I added the following line in order to have an origin that starts at the top left:

fabric.Object.prototype.originX = true; fabric.Object.prototype.originY = true;

Which is a line suggested by the creator of the library in order to use inheritance to set the origin to the top left for each object (see: Canvas coordinates in Fabric.js have offset). Leaving out this line of code gives a funky result. In the jsfiddle I added multiple blocks of code in order to try and accomplish my goal:

  1. In code block 1, I add a Rectangle in a group and position that group to (100,100). This works nicely as expected:

Adding a group containing single rectangle to position 100,100

  1. In code block 2, I define a Circle and add it to the group. This results in some funky positioning and changing of the dimensions of the group:

Adding a circle to previous group resulting in funky positioning

  1. Setting the circle to position (0,0) places it in what I think is the center of the previous bounding box, which doesn't make much sense to me since my origins are defined as top/left:

enter image description here

How do I position the circle so that it is in the top left corner of the rectangle AFTER having already created the group? There might be a bug at play here, or perhaps I'm not grasping the concept of positioning inside groups, and what adding something to a group does to the position/dimensions.

Upvotes: 1

Views: 5667

Answers (1)

Swapnil Jain
Swapnil Jain

Reputation: 1516

If you change the top and left coordinates of the circle as described below, it will position itself at the coordinates you desire.

var circle = new fabric.Circle({
  radius: 10,
  fill: 'red',
  originX: 'left',
  originY: 'top',
  left:group.left-(group.width/2),
  top:group.top-(group.height/2)
});

I am not too sure why I have to subtract half of group width and height from group's left and top. Here's your fiddle edited: http://jsfiddle.net/85x3hzx7/5/

Although, if you use the latest version of Fabric.js, you just have to set the left and top coordinates of new object to be added, to group's left and top coordinates. You can take a look at your code with latest version here: http://jsfiddle.net/rpko8z0r/3/

Please note that in new Fabric.js versions, default origin is set to top-left. So you don't need to set every object's origin to top-left, also following line of code is not needed.

fabric.Object.prototype.originX = true; 
fabric.Object.prototype.originY = true;

Upvotes: 4

Related Questions