javascriptfabricjs

Obtaining Object Coordinates in Fabric.js: Actual Coordinates vs Bounding Rectangles


Could you please help me understand how to obtain the actual coordinates of an object in fabric.js, rather than its bounding rectangle?

Triangle - find actual coordinates

Parallelogram - find actual coordinates

getBoundingRect is there to get the boundingBox coordinates. But I don't find any method or custom approach to find the actual shape coordinates as shown the below pictures.

I am using fabric 5.

const fc = new fabric.Canvas("c");


fc.on('selection:created', event => {
    console.log("Bounding Rect: ", event.target.item(0).getBoundingRect());
    console.log("How to find actual coord?? ");
});


const triangle1Options = {
    stroke: 'black',
    strokeWidth: 2,
    fill: 'red',
    left: 10,
    top: 10,
    width: 100,
    height: 100,
}

let triangle1 = new fabric.Triangle(triangle1Options);

const group1 = new fabric.Group([triangle1], {
      selectable: true,
      lockScalingFlip: true,
      lockUniScaling: true,
      subTargetCheck: true,
      lockScalingX: false,
      lockScalingY: false,
      objectCaching: false,
      noScaleCache: true
});

group1.add(triangle1);

fc.add(group1);


// Create the first parallelogram
var parallelogram1 = new fabric.Path('M 0 0 L 100 0 L 150 50 L 50 50 z', {
    left: 150,
    top: 50,
    stroke: 'black',
    strokeWidth: 2,
    fill: 'red',
});
const group2 = new fabric.Group([parallelogram1], {
      selectable: true,
      lockScalingFlip: true,
      lockUniScaling: true,
      subTargetCheck: true,
      lockScalingX: false,
      lockScalingY: false,
      objectCaching: false,
      noScaleCache: true
});


// Add the shapes and line to the canvas
fc.add(group2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.1.0/fabric.min.js"></script>
<canvas id="c" width="400" height="300" />

Any help is highly appreciated. I am open for new ideas for achieving my goal which is mentioned below.

Goal by this is to create an additional shape (a rect with text) on each vertex mid. but for that I need the actual coordinates of the shape.


Solution

  • Created a function getPolyVertices. The objective of the getPolyVertices function is to calculate and return of the transformed vertices of a polygon object in the canvas plane. It achieves this by applying transformation matrices to each vertex, using the canvas viewportTransform and the polygon's transform matrix, while also adjusting the origin of the polygon's plane to its center.

    function getPolyVertices(poly) {
      const points = poly.points,
        vertices = [];
      for (let i = 0; i < points.length; i++) {
        const point = points[i],
          nextPoint = points[(i + 1) % points.length],
          midPoint = {
            x: (point.x + nextPoint.x) / 2,
            y: (point.y + nextPoint.y) / 2
          };
        const x = midPoint.x - poly.pathOffset.x,
          y = midPoint.y - poly.pathOffset.y;
        vertices.push(
          fabric.util.transformPoint(
            { x: x, y: y },
            fabric.util.multiplyTransformMatrices(
              poly.canvas.viewportTransform,
              poly.calcTransformMatrix()
            )
          )
        );
      }
      return vertices;
    }
    

    We develop a function that modifies the placement of the circles each time the parallelogram undergoes movement, resizing, skewing, or rotation.

    function updateCirclesPosition() {
      const newVertices = getPolyVertices(polygon);
      newVertices.forEach((vertice, idx) => {
        const circ = circles[idx];
        circ.left = vertice.x;
        circ.top = vertice.y;
      });
    }
    
    group.on("scaling", updateCirclesPosition);
    group.on("skewing", updateCirclesPosition);
    group.on("rotating", updateCirclesPosition);
    group.on("moving", updateCirclesPosition);
    

    Sharing for other to help, here is a blog I wrote on this.