Fabric.js: [2.0] Objects inside group incorrect top/left

Created on 16 Aug 2017  路  13Comments  路  Source: fabricjs/fabric.js

Version

2.0.0-beta.6

Test Case

https://jsfiddle.net/L1vkund2/

Steps to reproduce

Take a look at the output of the fiddle below the canvas.

Expected Behavior

output should be
{
"redTop": 0,
"redLeft": 0,
"blueTop": 150,
"blueLeft": 150
}

Actual Behavior

{
"redTop": -125.5,
"redLeft": -125.5,
"blueTop": 24.5,
"blueLeft": 24.5
}

I am not sure how those values could be correct, no matter how the coordinate system is positioned. Maybe I am forgetting to call some function to correctly update the coordinates?

In the end, I just need to be able to get the coordinates of the object relative to the canvas, regardless of it being in a group. This issue was discussed here https://github.com/kangax/fabric.js/issues/1941. However, I don't think the issue was resolved in 2.0. I used to be able to use object.originalTop/object.originalLeft to calculate the position relative to the canvas but that has been removed in 2.0.

Most helpful comment

@aggrosoft @ivanjiang5628 below is the function I created to solve the issue:

fabric.Object.prototype.getAbsolute = function(key) {
  if (this.group) {
    if (key === 'top') {
      return this.calcTransformMatrix()[5];
    } else if (key === 'left') {
      return this.calcTransformMatrix()[4];
    } else if (key === 'angle') {
      return this.angle + this.group.angle;
    } else if (key === 'scaleX') {
      return this.scaleX * this.group.scaleX;
    } else if (key === 'scaleY') {
      return this.scaleY * this.group.scaleY;
    }
  }
  return this[key];
};

All 13 comments

There is nothing to fix here.
This is the group coordinate system, around the group center.
Is like that.
Could be done differently but there is really no reason to change that now.
Inside the group each object has a set of aCoords that should be relative to group.
You can multiply them for the matrix of the group: group.calcTransformMatrix() and you can obtain the current position of the object on the canvas.

Maybe a tutorial is usefull to understand those logics behind canvas transformation.
Having top-left unmodified would not have saved you when the group is rotated,scaled,skewed.

I suppose the futur pan/zoom tutorial there will have an example on the transformMatrix, perhaps it's a good way to also add an example on the group matrix transformations.

Got it. Using aCoords and group.calcTransformMatrix() did the trick. Thanks for the help!

@jfizz would you be willing to share your code to get the canvas relative coordinates of a grouped object?

to get the canvas relative top and left, take your object.

it has a group.

take matrix = group.calcTranformMatrix()

then do

fabric.util.transformPoint({top,left}, matrix)

that should do it

@asturur can you explain more about this?

an object inside a group is drawn after the 2d space has been changed by the group matrix.
the group matrix can be calculated with group.calcTransformMatrix()

The top left corner of the object ( x: -10, y: 7 ) as an example, is where it is, because before drawing at -10, 7 we transformed with the group.

Multipling the point by the matrix we get the position of the point on the canvas. All fabricJS stuff are based on logic similar to this.

newPoint = fabric.util.transformPoint({y: top, x: left}, matrix)

@aggrosoft @ivanjiang5628 below is the function I created to solve the issue:

fabric.Object.prototype.getAbsolute = function(key) {
  if (this.group) {
    if (key === 'top') {
      return this.calcTransformMatrix()[5];
    } else if (key === 'left') {
      return this.calcTransformMatrix()[4];
    } else if (key === 'angle') {
      return this.angle + this.group.angle;
    } else if (key === 'scaleX') {
      return this.scaleX * this.group.scaleX;
    } else if (key === 'scaleY') {
      return this.scaleY * this.group.scaleY;
    }
  }
  return this[key];
};

@asturur @jfizz Thank you guys so much,I resolved the problem by sending the right left top value to the server via newPoint = fabric.util.transformPoint({y: top, x: left}, matrix)

@asturur What did you change from 1.4.13 to 2.0.0 that causes groups of elements I had to disappear or show cut, icons missing... I am clueless although I looked in the release notes here:
http://fabricjs.com/changes-introduction

Could you elaborate?

1.4.13 was really long time ago.
Some major changes were, the stroke included in the dinensions, caching, removing pathGroups and probably more.

do you have one of those groups to render in a fiddle linked to 1.4.13?

Hey @asturur yeah I do, would love it if you could have some insights on this:
https://jsfiddle.net/vu7w6zkd/

The fiddle is incomplete, it does nothing.
It creates a group with fresh data, but what i m supposed to look at?

Was this page helpful?
0 / 5 - 0 ratings