How to calculate the unscaled and unrotated center of an object in absolute coordinates w.r.t top left corner of the canvas

Viewed 72

The origin i.e. (0,0) for the below code is the top left corner of the canvas. A rectangle is drawn that has been rotated by 45 degrees clockwise w.r.t the top-left corner(150,150) and it has been scaled by a factor of 2. From this state of the object, I want to calculate the unscaled and unrotated center of the object w.r.t the top-left corner of the canvas. In this particular case,

  • The current center, including rotate and scale, w.r.t top-left is (150,295)
  • Undoing the rotate brings the center to (250,250)
  • Undoing the scale too brings it to (200,200) which is the final value that I'm looking for

One way that I can try do this is to rotate and unscale manually

  • Get the center point, get the top-left point, use the fabric.util.rotatePoint to rotate the center back by -45 degrees. This gives the unrotated center point.
  • Then get the scaled width(object.getScaledWidth()) and unscaled width(object.width) and then reduce half the difference from the unrotated center point to get the unscaled center point.

I wanted to know if there was any easier way to do this using a transform matrix. In the code below, I'm trying to get the inverse of the current transform matrix of the rectangle object as mentioned here in the docs and then trying to apply the inverse matrix to the center point. This gives me the center point as 0,0 which is because transformPoint gives the point in a coordinate space where 0,0 is the center of the object. Any way to get the center w.r.t to the top-left of the canvas using this approach?

document.addEventListener("DOMContentLoaded", () => {
  var canvas = new fabric.Canvas("canvas"); 
  var mainBox = new fabric.Rect({
    fill: "#555",
    width: 100,
    height: 100,
    hasControls: true,
    hasBorders: true,
    selectable: true,
    left: 150,
    top: 150,
    angle: 45,
    scaleX: 2,
    scaleY: 2
  });
  canvas.add(mainBox);
  canvas.renderAll();
  const { x: parentCx, y: parentCy } = mainBox.getCenterPoint();
  const invertTransform = fabric.util.invertTransform(mainBox.calcTransformMatrix());
  const initCenterPoint = fabric.util.transformPoint(mainBox.getCenterPoint(), invertTransform);
  console.log("Initial center point", initCenterPoint.x, initCenterPoint.y);
});
canvas{
  border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
<canvas height="500" width="500" id="canvas"></canvas>
<button>Rotate</button>

0 Answers
Related