Fabric JS - Rotation of Clipped Image

by Eugene Vilder

HTML

<canvas id="canvas" width="800" height="500" style="border:1px solid #ccc"></canvas>

JavaScript

const multiply = fabric.util.multiplyTransformMatrices;
const invert = fabric.util.invertTransform;

const canvasZoomFactor = 1;
const db = {
  container: {
  	angle: 0,
    x: 100,
    y: 100,
    width: 200,
    height: 200
  },
  image: {
    angle: 0,
    x: 150,
    y: 150,
    width: 200,
    height: 200
  }

};

var canvas = new fabric.Canvas('canvas',{
  preserveObjectStacking: true,
  enableRetinaScaling: false,
  imageSmoothingEnabled: false
});
const rect = new fabric.Rect({
	originX: 'center',
  originY: 'center',
	fill: 'red',
	left: db.container.x,
  top: db.container.y,
  width: db.container.width,
  height: db.container.height
});
rect.rotate(db.container.angle);
rect.setPositionByOrigin({x: db.container.x, y: db.container.y}, 'left', 'top');

var image = new fabric.Image('');
canvas.add(rect,image);


rect.on('rotating', function(){
  console.log('Container angle is: ', this.angle, image.relationship);
  // Roation of image must be based on container origin point of rotation


    if (!image.relationship) {
      return;
    }
    
    var relationship = image.relationship;
    var newTransform = multiply(
      rect.calcTransformMatrix(),
      relationship
    );
    opt = fabric.util.qrDecompose(newTransform);
    image.set({
      flipX: false,
      flipY: false,
    });
    image.setPositionByOrigin(
      { x: opt.translateX, y: opt.translateY },
      'center',
      'center'
    );
    image.set(opt);
	image.setCoords();


});


image.setSrc('//img.stackshare.io/service/675/349dc6f270e53cbe09cd05f6c032fc67.png',function(img){
  img.scale(canvasZoomFactor).set({
    left: db.image.x,
    top: db.image.y,
    height: db.image.height,
    width: db.image.width,
    // selectable: false,
    clipTo: function (ctx) {
      ctx.rect(
        (db.container.x - db.image.x - db.image.width / 2) * canvasZoomFactor,
        (db.container.y - db.image.y - db.image.height / 2) * canvasZoomFactor,
        db.container.width * canvasZoomFactor,
       ...