title: FabricJS: How to auto-resize image to fit group or rectangle object?
body: <p><strong>Goal:</strong> I'm seeking to add an image to a FabricJS group or rectangle object, and for the image to maintain it's original aspect ratio and center fit it's parent width/height.</p>
  
  <p>I don't want the image overflow to show, but will show the overflow as a less opaque green in the examples below:</p>
  
  <hr>
  
  <p><strong>Landscape Image Example</strong>:</p>
  
  <p>If it was a landscape oriented image, it would scale to max height, but then center itself with regards to width placement:</p>
  
  <p><a href="https://i.stack.imgur.com/6cOQe.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6cOQe.jpg" alt="Image resized within fabricjs rectangle - landscape orientation"></a></p>
  
  <p>Since I'm not looking for the image overflow to show, the final product should look like this:</p>
  
  <p><a href="https://i.stack.imgur.com/6rSct.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6rSct.jpg" alt="Image resized within fabricjs rectangle final look - landscape orientation"></a></p>
  
  <hr>
  
  <p><strong>Portrait Image Example</strong>:</p>
  
  <p>Similarly, if the image was portrait oriented, the image would scale 100% in width, but center itself in height:</p>
  
  <p><a href="https://i.stack.imgur.com/FPQW8.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FPQW8.jpg" alt="Image resized within fabricjs rectangle - portrait orientation"></a></p>
  
  <p>And then negating the overflow, this is what I'm looking for as a final product:</p>
  
  <p><a href="https://i.stack.imgur.com/BhgWJ.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/BhgWJ.jpg" alt="Image resized within fabricjs rectangle final product - portrait orientation"></a></p>
  
  <hr>
  
  <p>Here's my stackblitz so far: <a href="https://stackblitz.com/edit/angular-gpfkkw" rel="nofollow noreferrer">https://stackblitz.com/edit/angular-gpfkkw</a></p>
  
  <p>With the base-case code as follows:</p>
  
  <pre><code>this.canvas = new fabric.Canvas('canvas');
  var rect = new fabric.Rect({
      left: 100,
      top: 50,
      width: 450,
      height: 200,
      fill: '#e3e3e3',
  });
  
  var rectGroup = new fabric.Group([rect], {
      name: 'Rectangle',
  });
  
  this.canvas.add(rectGroup);
  
  fabric.Image.fromURL('https://placehold.it/888x500&amp;text=16:9', (img) =&gt; {
      let bounds = rectGroup.getBoundingRect();
  
      const scaleFactor = Math.min(
          Math.min(bounds.width / img.width),
          Math.min(bounds.height / img.height)
      );
      img.scale(scaleFactor);
  
      img.set({
          top: bounds.top + Math.max(bounds.height - img.height * scaleFactor, 0)/2,
          left: bounds.left + Math.max(bounds.width - img.width * scaleFactor, 0)/2,
      });
  
      rectGroup.addWithUpdate(img);
      this.canvas.renderAll();
  }
  </code></pre>
  
  <p>This is obviously not the right solution, but a start. Any advice?</p>