JSFiddle - React, Tailwind, and code Playground

by fxi

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/fabric.min.js"></script>
<canvas id="ex7" width=400 height=400></canvas>

CSS

body,
html {
  width: 100%;
  height: 100%;
}

#ex7 {
  width: 100%;
  height: 100%;
}

JavaScript

(function() {
  var canvas = new fabric.Canvas('ex7');
  var clip = new fabric.Rect({
    fill: 'rgba(0,0,0,0.2)',
    left: 100,
    top: 100,
    width: 99,
    height: 99
  });

  clip.setControlsVisibility({
    mtr: false,
  });

  fabric.Image.fromURL('https://placekitten.com/200/200', function(img) {
    img.setControlsVisibility({
      mtr: false,
      mt: false,
      ml: false,
      mr: false,
      mb: false,
      tl: false,
      tr: false,
      br: true,
      bl: false
    });

    img.scale(0.5).set({
      left: 100,
      top: 100
    });

    canvas.add(img);

    function keepInside(o) {

      var mvImg = o instanceof Object &&
        o.target === clip &&
        o.transform.action == "drag"

      var cw = clip.getScaledWidth();
      var iw = img.getScaledWidth();

      var ih = img.getScaledHeight();
      var ch = clip.getScaledHeight();

      var il = img.left;
      var cl = clip.left;

      var it = img.top;
      var ct = clip.top;

      var ir = il + iw;
      var cr = cl + cw;

      var ib = it + ih;
      var cb = ct + ch;

      if (cw > iw) {
        clip.scaleToWidth(iw);
        clip.left = il;
      } else {
        if (cl < il) {
          if (mvImg) {
            img.left = cl;
          } else {
            clip.left = il;
          }
        }
        if (cr > ir) {
          if (mvImg) {
            img.left = cr - iw;
          } else {
            clip.left = ir - iw
          }
        }

      }
      if (ch > ih) {
     
        clip.top = it;
      } else {
        if (ct < it) {
          if (mvImg) {
            img.top = ct;

          } else {
            clip.top = it;
          }
        }

        if (cb > ib) {
          if (mvImg) {
            img.top = cb - ih;
          } else {
            clip.top = ib - ih;

          }

        }

      }

      canvas.bringToFront(clip);
    }

    // 
    img.on('moving', keepInside);
    clip.on('moving', keepInside);
    clip.on('scaling', keepInside);
...