clipto selection

by SooChangLee

HTML

<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="canvas" width="600" height="600"></canvas>

CSS

canvas {
    border: 1px solid #ccc;
}

JavaScript

var img01URL = 'http://fabricjs.com/assets/pug_small.jpg';
var img02URL = 'http://fabricjs.com/lib/pug.jpg';
 
var canvas = new fabric.Canvas('canvas', {
  backgroundColor: 'lightgrey',
   
  width: 500,
  height: 500,
 
  selection:            false,              // Disable group selection
  snapAngle:            90,
  uniScaleTransform:    false,
  controlsAboveOverlay: false,
  // preserveObjectStacking: true,              // Don't push the active object to the topmost layer
  perPixelTargetFind:   true,
});
 
var slot1 = new fabric.Rect({
  originX: 'left',
  originY: 'top',
  left: 10,
  top: 10,
  width: 150,
  height: 150,
  fill: 'transparent',
  stroke: 'red',
  strokeWidth: 1,
  selectable: false,
  evented: false,
  objectCaching: false
});
var slot2 = new fabric.Rect({
  originX: 'left',
  originY: 'top',
  left: 180,
  top: 10,
  width: 200,
  height: 200,
  fill: 'transparent',
  stroke: 'blue',
  strokeWidth: 1,
  selectable: false,
  evented: false,  
  objectCaching: false
});
 
// Since the `angle` property of the Image object is stored 
// in degrees, we'll use this to convert it to radians.
function degToRad(degrees) {
  return degrees * (Math.PI / 180);
}
 
function clipBySlot(ctx, image, slot) {
  //console.log("image scale", image.scaleX, "x", image.scaleY);
  //console.log("slot pos", slot.left, "x", slot.top);
  var scaleXTo1 = (1 / image.scaleX);
  var scaleYTo1 = (1 / image.scaleY);
   
  // Save context of the canvas so it can be restored after the clipping
  ctx.save();
   
  //ctx.translate(0, 0);
  ctx.rotate(degToRad(image.angle * -1));
  ctx.scale(scaleXTo1, scaleYTo1);
  //console.log("ctx scale", ctx.scaleX, "x", ctx.scaleY);
   
  ctx.beginPath();
   
  const boundingRect = image.getBoundingRect();
  //console.log(`[left] ${image.left} - (${boundingRect.width} / 2)`);
   
  ctx.rect(
    slot.left - image.left - Math.floor(boundingRect.width / 2),
    slot.top - image.top - Math.floor(boundingRect.height / 2),
    slot.width,
 ...