Controls outside of canvas

by Steve Eberhardt

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.min.js"></script>
<div id="master-container">
  <div class="overlay-container">
    <div id="floating-controls">
    
    </div>
  </div>
  <div class="canvases-container">
    
    <div class="canvas-holder">
      <canvas id="c1" width="200" height="300"></canvas>
    </div>
    <div class="canvas-holder">
      <canvas id="c2" width="200" height="300"></canvas>
    </div>
  </div>

</div>

CSS

#master-container {
  display: block;
  width: 100%;
  height: 100%;
  position: absolute;
}

#floating-controls {
  position: absolute;
  border: 1px solid blue;
  width: 100px;
  height: 100px;
  
}

.overlay-container {
  position: absolute;
  width: 100%;
  height: 100%;
}

.canvas-holder {
  margin: 15px;
}

canvas {
  border: 1px solid grey;
}

.canvas-holder {
  display: inline-block;
}

#img-list {}

#img-list img {
  margin: 5px;
  cursor: move;
  display: inline-block;
}

#img-list img:hover {
  opacity: 0.9;
}

JavaScript

var canvasArray = initializeCanvases(["c1","c2"]);

function initializeCanvases(canvasIDs) {
	var array = [];
  canvasIDs.forEach(function(canvasID, index) {
    var canvas = new fabric.Canvas(canvasID);
    canvas.on({
      "object:moving": function(e) {
        var bounds = getImageBounds(e.target);
        console.log(bounds);
        if(bounds.right > canvas.width) {
        	console.log(e.target.canvas);
        }
      }
    });
    array.push(canvas);
  });
  return array;
}

fabric.Canvas.prototype.set({
  preserveObjectStacking: true
});

fabric.Object.prototype.set({
  originX: "center",
  originY: "center"
});

fabric.Image.prototype._controlsVisibility = {
  tl: true,
  tr: true,
  br: true,
  bl: true,
  ml: false,
  mt: false,
  mr: false,
  mb: false,
  mtr: true
};

addImage([canvasArray[0], canvasArray[1]], "https://i.postimg.cc/wBkvCYhM/pexels-tae-fuller-1141853.jpg", 200, 150);

function getImageBounds(obj) {
  var bounds = obj.getBoundingRect();
  	bounds.right = bounds.left + bounds.width;
  	bounds.bottom = bounds.top + bounds.height;
  return bounds;
}

function addImage(canvases, src, x, y) {
	//uses current time as a simple unique id for the image
  var id = Date.now();
  canvases.forEach(function(canvas, index) {
    fabric.Image.fromURL(src, function(img) {
      img.set({
        left: x,
        top: y,
        scaleX: 0.5,
        scaleY: 0.5,
        id: id
      }, {
        crossOrigin: 'anonymous'
      });
      canvas.add(img).setActiveObject(img);
    });
  });
}