esims
esims

Reputation: 420

Fabric.js: custom rotation point

I have found a workaround here (see code below), but I wonder if Fabric has built-in support to set the rotation point of an object to a specific place.

function rotateObject(fabObj, angleRadian, pivotX, pivotY) {
  ty = pivotY - fabObj.height / 2.0;
  tx = pivotX - fabObj.width / 2.0;
  if (angleRadian >= Math.PI * 2) {
    angleRadian -= Math.PI * 2;
  }
  angle2 = Math.atan2(ty, tx);
  angle3 = (2 * angle2 + angleRadian - Math.PI) / 2.0;
  pdist_sq = tx * tx + ty * ty;
  disp = Math.sqrt(2 * pdist_sq * (1 - Math.cos(angleRadian)));
  fabObj.set({transformMatrix:[
    Math.cos(angleRadian),
    Math.sin(angleRadian),
    -Math.sin(angleRadian),
    Math.cos(angleRadian),
    disp * Math.cos(angle3),
    disp * Math.sin(angle3)
  ]});
}

Upvotes: 3

Views: 5161

Answers (2)

Dmytro Myronenko
Dmytro Myronenko

Reputation: 73

Rotation on fabricjs is around the center point. This fuction is on developmenting... but I have implemented to line rotation. Redrawing line from custom center point to mouse position. it works well for me.

Upvotes: 2

AndreaBogazzi
AndreaBogazzi

Reputation: 14731

There is no built in method.

By default mouse rotation on fabricjs is around the center point.

If you deactivate centeredRotation on objects, setting it to false:

fabric.Object.prototype.centeredRotation = false

the object will start to rotate around the originX and originY position.

Then you can set for each object a specific originX and originY, that can be numeric and represent any point inside the object ( with values ranging from 0 to 1 ) i m not even sure if you can do it with points outside the object.

At that point the object rotates around that point, just setting the angle property to a desired angle.

Consider that now also position is relative to that origin.

As a side not, do not set transformMatrix of an object. is unsupported and will give you weird controls in case of interactivity with controls.

In your specific example, once found the matrix:

var matrix = [
  Math.cos(angleRadian),
  Math.sin(angleRadian),
  -Math.sin(angleRadian),
  Math.cos(angleRadian),
  disp * Math.cos(angle3),
  disp * Math.sin(angle3)
];

var options = fabric.util.qrDecompose(matrix);

object.set(options);
object.setPositionByOrigin({ x: options.translateX, y: options.translateY }, 'center', 'center');

this should give you same effect but being supported by fabricjs better.

Upvotes: 3

Related Questions