6

How can I get canvas-relative position (top, left) of triangle inside an group as bellow image?

I followed this topic: How to get the canvas-relative position of an object that is in a group? but it only right when group is not rotated.

enter image description here

Anh Tú
  • 636
  • 7
  • 21
  • I know in ThreeJS you can ray trace from an origin and use the vector returned from the object you've pointed too to figure out the pixel position on the canvas. I'm not sure if that sort of functionality exists in Fabric but conceptually those are the types of tools you can use to figure this out programmatically. – Dan Kanze Oct 31 '18 at 20:38

2 Answers2

2

Working example you may find here: http://jsfiddle.net/mmalex/2rsevdLa/

fabricJs: calculate canvas space coordinates of child object in the group

Fabricjs provides a comprehensive explanation of how transformations are applied to the objects: http://fabricjs.com/using-transformations

Quick answer: the coordinates of an object inside the group is a point [0,0] transformed exactly how the object in the group was transformed.

Follow my comments in code to get the idea.

    // 1. arrange canvas layout with group of two rectangles
    var canvas = new fabric.Canvas(document.getElementById('c'));

    var rect = new fabric.Rect({
      width: 100,
      height: 100,
      left: 50,
      top: 50,
      fill: 'rgba(255,0,0,0.25)'
    });
    var smallRect = new fabric.Rect({
      width: 12,
      height: 12,
      left: 150 - 12,
      top: 50 + 50 - 12 / 2 - 10,
      fill: 'rgba(250,250,0,0.5)'
    });

    // 2. add a position marker (red dot) for visibility and debug reasons
    var refRect = new fabric.Rect({
      width: 3,
      height: 3,
      left: 100,
      top: 100,
      fill: 'rgba(255,0,0,0.75)'
    });

    var group = new fabric.Group([rect, smallRect], {
      originX: 'center',
      originY: 'center'
    });
    canvas.add(group);
    canvas.add(refRect);
    canvas.renderAll();

    // 3. calculate coordinates of child object in canvas space coords
    function getCoords() {
      // get transformation matrixes for object and group individually
      var mGroup = group.calcTransformMatrix(true);

      // flag true means that we need local transformation for the object,
      // i.e. how object is positioned INSIDE the group
      var mObject = smallRect.calcTransformMatrix(true);

      console.log("group: ", fabric.util.qrDecompose(mGroup));
      console.log("rect: ", fabric.util.qrDecompose(mObject));

      // get total transformattions that were applied to the child object,
      // the child is transformed in following order:
      // canvas zoom and pan => group transformation => nested object => nested object => etc...
      // for simplicity, ignore canvas zoom and pan
      var mTotal = fabric.util.multiplyTransformMatrices(mGroup, mObject);
      console.log("total: ", fabric.util.qrDecompose(mTotal));

      // just apply transforms to origin to get what we want
      var c = new fabric.Point(0, 0);
      var p = fabric.util.transformPoint(c, mTotal);
      console.log("coords: ", p);
      document.getElementById("output").innerHTML = "Coords: " + JSON.stringify(p);

      // do some chores, place red point
      refRect.left = p.x - 3 / 2;
      refRect.top = p.y - 3 / 2;
      canvas.bringToFront(refRect);
      canvas.renderAll();
    }
Alex Khoroshylov
  • 2,234
  • 1
  • 17
  • 28
0

a very simple way to get topleft is

var cords = object._getLeftTopCoords();
cords.x and cord.y will give you the result
Dharman
  • 30,962
  • 25
  • 85
  • 135