1

I have a project that I'm working on, and am trying to get a Fabric.JS to allow me to rotate & scale items, but only to the max scale of a bounding box. I tried quite a few combinations on the object:scaling event, to no avail. I have left a portion of the scaling event commented out, but though all my tries (determining movingBox width and such), i was unable to constrain the proportions of the square to the box.

Notice, before transforming the box stays within the outer bounds... exactly the functionality I desire. I just need the same functionality during the rotate & resize methods... which I assume we'll need to tap into the rotating & scale methods. Any help in modifying/adding to this to make these things possible, would be incredibly helpful.

Thanks,

$(function () {

            var canvas = new fabric.Canvas("c");
            canvas.setHeight(600);
            canvas.setWidth(400);

            var boundingBox = new fabric.Rect({
                fill: "rgba(255, 255, 255, 0.0)",
                width: 98,
                height: 200,
                hasBorders: false,
                hasControls: false,
                lockMovementX: true,
                lockMovementY: true,
                evented: false,
                stroke: "black"
            });

            var movingBox = new fabric.Rect({
                width: 50,
                height: 50,
                hasBorders: false,
                hasControls: true,
                lockRotation: false
            });

            canvas.on("object:moving", function () {
                var top = movingBox.top;
                var bottom = top + movingBox.height;
                var left = movingBox.left;
                var right = left + movingBox.width;

                var topBound = boundingBox.top;
                var bottomBound = topBound + boundingBox.height;
                var leftBound = boundingBox.left;
                var rightBound = leftBound + boundingBox.width;

                movingBox.setLeft(Math.min(Math.max(left, leftBound), rightBound - movingBox.width));
                movingBox.setTop(Math.min(Math.max(top, topBound), bottomBound - movingBox.height));
            });

           //canvas.on("object:scaling", function () {
           //    var top = movingBox.top;
           //    var bottom = top + movingBox.height;
           //    var left = movingBox.left;
           //    var right =  movingBox.width;
           //
           //    var topBound = boundingBox.top;
           //    var bottomBound = topBound + boundingBox.height;
           //    var leftBound = boundingBox.left;
           //    var rightBound = leftBound + boundingBox.width;
           //      
           //   // movingBox.setWidth // need alg here
           //    //movingBox.setHeight // need alg here
           //});


            canvas.add(boundingBox);
            canvas.add(movingBox);




        });
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div style="position: absolute; top: 149px; left: 151px;">
            <canvas id="c"></canvas>
        </div>
Sean Haddy
  • 1,630
  • 1
  • 16
  • 25
  • Duplicate of http://stackoverflow.com/questions/34640471/fabric-js-constrain-resize-scale-to-canvas-object – AndreaBogazzi Jan 28 '16 at 14:18
  • Yes, I previously saw that question... unfortunately the resize method on it is incredibly buggy (only can resize from bottom right corner), and does not handle rotation... – Sean Haddy Jan 29 '16 at 16:56
  • Opening another question will not improve situation, that code should be improved, the main point is that you cannot just rely on getting out of the box but also calculate right dimension by yourself. – AndreaBogazzi Jan 30 '16 at 12:16

1 Answers1

0

For the scale you can use the fiddle below to set the width and height when you are scaling and then you can limit the figure width and height

var canvas = new fabric.Canvas("c1");


reinit()
canvas.on({
    'object:scaling': function(e) {
     
        var obj = e.target,
            w = obj.width * obj.scaleX,
            h = obj.height * obj.scaleY,
            s = obj.strokeWidth;
            
        console.log(obj.width, obj.scaleX, h,w,s)
  
        obj._objects[0].set({
            'height'     : obj.height,
            'width'      : obj.width,
            'scaleX'     : 1,
            'scaleY'     : 1,
            h: h,
            w: w
            //top: 1,
            //left: 1,
        });
        
        /*e.target.set({
            'height'     : h,
            'width'      : w,
            'scaleX'     : 1,
            'scaleY'     : 1
        });*/
    }
});

canvas.on({
    'object:modified': function(e) {
    console.log(e)
    //e.target.set({scaleX:1, scaleY:1})
     group = e.target
     rect = e.target._objects[0]
      rect.set({height:rect.h, width: rect.w})
      console.log('r',rect.width, group.width)
      text = group._objects[1]
      canvas.remove(group)
      canvas.add(new fabric.Group([rect,text], {
       top: group.top,
        left: group.left
      }))
    }

});

function reinit(){
 var el = new fabric.Rect({
    originX: "left",
    originY: "top",
    
    stroke: "rgb(0,0,0)",
    strokeWidth: 1,
    fill: 'transparent',
    opacity: 1,
    width: 200,
    height: 200,
    cornerSize: 6
 });

  var text = new fabric.IText('test', {  fontSize: 16});

  var group = new fabric.Group([ el, text ], {
     width: 200,
     height: 200,
     left: 5,
     top: 5,
  });
  canvas.add(group);
 canvas.renderAll();

}

http://jsfiddle.net/davidtorroija/qs0ywh8k/

David Torroija
  • 593
  • 5
  • 17