JSFiddle - React, Tailwind, and code Playground

by Steve Eberhardt

HTML

<canvas width="600" height="600" id="fabricCanvas"></canvas>
<script src="https://unpkg.com/[email protected]/dist/fabric.js"></script>

CSS

canvas {
  border: 1px solid #999;
}

JavaScript

var canvas = window._canvas = new fabric.Canvas('fabricCanvas');
canvas.add(
  new fabric.Rect({
    fill: 'red',
    width: 50,
    height: 50,
    snapAngle: 15,
    lockMovementX: false,
    lockMovementY: false,
    visible: true,
    lockScalingFlip: true,
    hasControls: true,
    transparentCorners: false,
    cornerSize: 11,
    cornerColor: 'gray',
    cornerStyle: 'circle',
    noScaleCache: false,
    strokeWidth: 0
  }));

this.canvas.on('object:scaling', function(e) {
  scaling(e);
});
this.canvas.on('object:moving', function(e) {
  movingRotatingWithinBounds(e);
});
this.canvas.on('object:rotated', function(e) {
  movingRotatingWithinBounds(e);
});

let scalingProperties = {
  'left': 0,
  'top': 0,
  'scaleX': 0,
  'scaleY': 0
}

function scaling(e) {
  let shape = e.target;
  let maxWidth = shape.canvas.width;
  let maxHeight = shape.canvas.height;

  //left border
  if(shape.left < 0) {
    shape.left = scalingProperties.left;
    shape.scaleX = scalingProperties.scaleX
  } else {
    scalingProperties.left = shape.left;
    scalingProperties.scaleX = shape.scaleX;
  }

  //right border
  if((scalingProperties.scaleX * shape.width) + shape.left >= maxWidth) {
    shape.scaleX = (maxWidth - scalingProperties.left) / shape.width;
  } else {
    scalingProperties.scaleX = shape.scaleX;
  }

  //top border
  if(shape.top < 0) {
    shape.top = scalingProperties.top;
    shape.scaleY = scalingProperties.scaleY;
  } else {
    scalingProperties.top = shape.top;
    scalingProperties.scaleY = shape.scaleY;
  }

  //bottom border
  if((scalingProperties.scaleY * shape.height) + shape.top >= maxHeight) {
    shape.scaleY = (maxHeight - scalingProperties.top) / shape.height;
  } else {
    scalingProperties.scaleY = shape.scaleY;
  }
}

function movingRotatingWithinBounds(e) {
  const obj = e.target;
  // if object is too big ignore
  if(obj.height > obj.canvas.height || obj.width > obj.canvas.width){
    return;
  }
  obj.setCoords();
  // top-left ...