Fabricjs image crop

cropX, cropY

by Steve Eberhardt

HTML

<script src="https://unpkg.com/fabric@latest/dist/fabric.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Image crop</title>
  <script src="https://unpkg.com/fabric@latest/dist/fabric.js"></script>
</head>
<body>
  <canvas id="canvas" width="600" height="350"></canvas>
  <button id="toggle-crop">Toggle Crop</button>
  <button id="save">Save as json</button>
  <button id="create">Create from json</button>
  <script src="app.js"></script>
</body>
</html>

JavaScript

(function (global) {
  "use strict";

  const fabric = global.fabric || (global.fabric = {});

  fabric.Object.prototype.cornerStyle = "circle";

  const canvas = new fabric.Canvas("canvas");

  const UserImage = fabric.util.createClass(fabric.Image, {
    type: "userImage",
    
    disableCrop: false,
    
    clipPosition: null,
    
    cropWidth: 0,
    
    cropHeight: 0,

    initialize(element, options) {
      options = options || {};

      options = Object.assign({
        cropHeight: this.height,
        cropWidth: this.width
      }, options);

      if (!("clipPosition" in options) || Object.values(fabric.UserImage.CLIP_POSITIONS).indexOf(options.clipPosition) === -1) {
        options.clipPosition = fabric.UserImage.CLIP_POSITIONS.CENTER_MIDDLE;
      }
      
      this.callSuper("initialize", element, options);

      if (!this.disableCrop) {
        this.applyCrop();
      }
    },

    getCrop(image, size) {
      const width = size.width;
      const height = size.height;    
      const aspectRatio = width / height;
  
      let newWidth;
      let newHeight;
      
      const imageRatio = image.width / image.height;

      if (aspectRatio >= imageRatio) {
        newWidth = image.width;
        newHeight = image.width / aspectRatio;
      } else {
        newWidth = image.height * aspectRatio;
        newHeight = image.height;
      }
  
      let x = 0;
      let y = 0;

      if (this.clipPosition === fabric.UserImage.CLIP_POSITIONS.LEFT_TOP) {
        x = 0;
        y = 0;
      } else if (this.clipPosition === fabric.UserImage.CLIP_POSITIONS.LEFT_MIDDLE) {
        x = 0;
        y = (image.height - newHeight) / 2;
      } else if (this.clipPosition === fabric.UserImage.CLIP_POSITIONS.LEFT_BOTTOM) {
        x = 0;
        y = image.height - newHeight;
      } else if (this.clipPosition === fabric.UserImage.CLIP_POSITIONS.CENTER_TOP) {
        x = (image.width - newWidth) / 2;
        y = 0;
      } else if (this.clipPosition ===...