(updated ) by

Fabric active selection is a group

In fabric when you select objects they get added either as the target object or in a new group containing the selected objects. This generally works fine until you want to get the location of a selected item in a group. Doing object.top or object.left now has changed from the original location to this new location based on the group.

This can be bad if you are trying to get or save the location of all the selected objects.

canvas.getActiveObjects().forEach(({ top, left, id }) => {
  // Save has the incorrect top, left due to group transformations
  save(id, { top, left });
});

To combat this you need to apply the group transformations to the objects.

canvas.getActiveObjects().forEach(object => {
  // 1. get the matrix for the object.
  const matrix = ObjectInGroup.calcTransformMatrix();
  // 2. choose the point you want, for example top, left.
  // (active selection origin is center, center)
  const point = { x: -ObjectInGroup.width / 2, y: ObjectInGroup.height / 2 };
  // 3. transform the point
  const pointOnCanvas = fabric.util.transformPoint(point, matrix);

  save(object.id, { top: pointOnCanvas.y, left: pointOnCanvas.x });
});

Now you have the adjusted position.

You could also do object.toObject() that creates an exportable version that calculates the group transformations for you.

canvas.getActiveObjects().forEach(object => {
  const { top, left } = object.toObject();
  save(object.id, { top, left });
});

See fabric.js#801 for more info.