#StackBounty: #javascript #canvas #html5-canvas #fabricjs How to Limit Object inside Transparent Rectangle Area – FabricJS?

Bounty: 50

I am implementing designer functionality using FabricJS in my side. My Idea is to set the background image using setBackgroundImage from fabric, also i add specific area of transparent rectangle with size and position fetch from JCrop. Now come to my question, i want to restrict the object placement within that specific area of transparent rectangle. Let say i want to add text/image/shapes that should be in that limited area, i able to implement the background image, position of transparent rectangle and even circle shape object but i unable to find details to limit object place it inside transparent rectangle and only in that region.

Here is my below code and working fiddle, If you see it in fiddle the image where you need to select the cropping portion and below that canvas background with transparent rectangle which is the one of same like crop selection. Now i want to limit the object placement anything to be in that transparent rectangle, right now i can place object in anywhere in the canvas.


   <img src="https://images.unsplash.com/photo-1595438337199-d50ba5072c7e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=330&q=80" id="target">

   <div class="canvas-container" style="position: relative; user-select: none;">
     <canvas id="c1" width="600" height="600" style="border:1px solid #ccc; position: absolute;  left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas>


function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
  var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
  return {
    width: srcWidth * ratio,
    height: srcHeight * ratio,
    aspectratio: ratio

jQuery(function($) {
  var img = new Image();
  img.onload = function() {
    var data = calculateAspectRatioFit(this.width, this.height, '400', '600');
    jQuery('#target').attr('width', data.width);
    jQuery('#target').attr('height', data.height);
    jQuery('#pdr-drawing-area').html("Aspect Ratio: " + data.aspectratio);
    const stage = Jcrop.attach('target');
    stage.listen('crop.change', function(widget, e) {
      const pos = widget.pos;
      console.log(pos.x, pos.y, pos.w, pos.h);
      //fabric js
      var canvas = new fabric.Canvas('c1');
      var center = canvas.getCenter();
      var img = 'https://images.unsplash.com/photo-1595438337199-d50ba5072c7e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=330&q=80';
      canvas.setBackgroundImage(img, function() {
        canvas.backgroundImage && canvas.backgroundImage.scaleToWidth(data.width);
        canvas.backgroundImage && canvas.backgroundImage.scaleToHeight(data.height);
      console.log(pos.x * data.aspectratio);
      var rect = new fabric.Rect({
        left: pos.x,
        top: pos.y,
        fill: 'transparent',
        width: (pos.w),
        height: (pos.h),
        strokeDashArray: [5, 5],
        stroke: "black",
        selectable: false,
        evented: false,
        //visible: false

      canvas.add(new fabric.Circle({
        radius: 30,
        fill: '#f55',
        top: pos.y + 2,
        left: pos.x + 2

   img.src = 'https://images.unsplash.com/photo-1595438337199-d50ba5072c7e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=330&q=80';

Get this bounty!!!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.