Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

set Min and Max resize limits for fabric object

Tags:

fabricjs

I am using fabric js for resizing object i want user to resize the object with in min&max limits. How to do this with fabric js.

I tried properties like

lockScalingX,lockScalingY,lockMomentX,lockMomentY but no luck.

Any help will be grateful.

Thanks,

like image 887
Bikshu s Avatar asked Oct 03 '16 08:10

Bikshu s


3 Answers

There is no way to do it natively in fabric but you can hook in to the scaling event and make any modification to the object you should like. In this code I stop the scaling as well as correct fabric from shifting the top/left when I am over riding the scaling.

window.canvas = new fabric.Canvas('c');

var rect = new fabric.Rect({ 
  left: 100, 
  top: 100, 
  width: 50, 
  height: 50, 
  fill: '#faa', 
  originX: 'left', 
  originY: 'top',
  stroke: "#000",
  strokeWidth: 1,
  centeredRotation: true
});

canvas.add(rect);

var maxScaleX = 2;
var maxScaleY = 2;

rect.on('scaling', function() {
  if(this.scaleX > maxScaleX) {
    this.scaleX = maxScaleX;
    this.left = this.lastGoodLeft;
    this.top = this.lastGoodTop;
  }
  if(this.scaleY > maxScaleY) {
    this.scaleY = maxScaleY;
    this.left = this.lastGoodLeft;
    this.top = this.lastGoodTop;
  }
  this.lastGoodTop = this.top;
  this.lastGoodLeft = this.left;
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.4/fabric.min.js"></script>
<canvas id="c" width="600" height="600"></canvas>
like image 169
StefanHayden Avatar answered Oct 17 '22 10:10

StefanHayden


Might come in handy for people searching for similar answers.

You can natively set the minimum limit for scaling by setting minScaleLimit. However, there isn't an out-of-the-box solution available for setting maximum limit.

like image 25
Nitheesh A S Avatar answered Oct 17 '22 12:10

Nitheesh A S


i addapted the drag limit algorithm that i had. In my specific case, i have a canvas element with a background image and i had to limit the other objects resizing with the background image limits so i added extra margins to do that. But if you need to limit the objects resizing only with the canvas size you can set the extra margins to 0.

 //Limit the draggable zone
            this.canvas.on("object:scaling", function (e) {
                let obj = e.target;
                let canvas = obj.canvas;
                let zoom = canvas.getZoom();

                let pan_x = canvas.viewportTransform[4];
                let pan_y = canvas.viewportTransform[5];

                // width & height we are constraining to must be calculated by applying the inverse of the current viewportTransform
                let canvas_height = canvas.height / zoom;
                let canvas_width = canvas.width / zoom;

                let totalWidth = obj.width * obj.scaleX;
                let totalHeight = obj.height * obj.scaleY;

                // if you need margins set them here
                let top_margin = marginYTop;
                let bottom_margin = marginYBottom;
                let left_margin = marginXLeft;
                let right_margin = marginXRight;

                let top_bound = top_margin - pan_y;
                let bottom_bound = canvas_height - bottom_margin - pan_y;
                let left_bound = left_margin - pan_x;
                let right_bound = canvas_width - right_margin - pan_x;

                if (obj.top < top_bound || (obj.top + totalHeight) > bottom_bound) {
                    obj.scaleY = obj.canvas.lastScaleY;
                    obj.set("top", top_bound);
                }
                if (obj.left < left_bound || (obj.left + totalWidth) > right_bound) {
                    obj.scaleX = obj.canvas.lastScaleX;
                    obj.set("left", left_bound);
                }

                obj.canvas.lastScaleY = obj.scaleY;
                obj.canvas.lastScaleX = obj.scaleX;
            });
like image 23
Ilan Baron Avatar answered Oct 17 '22 11:10

Ilan Baron