JSFiddle - React, Tailwind, and code Playground

by endeepak

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
<canvas id="c" width="450" height="400"></canvas>

CSS

#c {
  outline: 1px solid #ccc
}

JavaScript

var canvas = new fabric.Canvas('c');

var Container = function(canvas, objects) {
  var self = this;
  self.padding = 10;
  self.objects = objects || [];
  self.boundary = new fabric.Rect({
      left: 50 - self.padding,
      top: 50 - self.padding,
      strokeDashArray: [1, 1],
      stroke: 'black',
      strokeWidth: 1,
      fill: 'rgba(0,0,0,0)',
      hasControls: true,
      selectable: true,
      lockMovementX: false,
      lockMovementY: false
    });
  
  self.add = function(fabricObject) {
  	self.objects.push(fabricObject);
    drawBoundary();
  }
  
  self.remove = function(fabricObject) {
  	self.objects.remove(fabricObject);
    drawBoundary();
  }

  self._allObjects = function() {
  	return _.union([self.boundary], self.objects)
  }

  self.contains = function(object) {
  	return _.contains(self.objects, object)
  }

	var drawBoundary = function() {
    var left = _.min(_.map(self._allObjects(), function(object) {
      return object.getLeft();
    }));
    var top = _.min(_.map(self._allObjects(), function(object) {
      return object.getTop();
    }));
    var right = _.max(_.map(self._allObjects(), function(object) {
      return object.getLeft() + object.getWidth();
    }));
    var bottom = _.max(_.map(self._allObjects(), function(object) {
      return object.getTop() + object.getHeight();
    }));
    var width = right - left + self.padding;
    var height = bottom - top + self.padding;
    self.previousBoundaryPosition = {left: left, top: top};
    self.boundary.set({
      left: left, 
      top: top,
      width: width-1, 
      height: height-1,
      scaleX: 1,
      scaleY: 1
    });
    canvas.renderAll();  	
  }

	self.render = function() {
  	canvas.add(self.boundary);
    self.objects.forEach(function(object) {
    	//canvas.add(object);
    });
    drawBoundary();
    canvas.renderAll();

		// ensure bondary is updated when objects are modified
    canvas.on('object:modified', function(e) {
      if (self.contains(e.target))...