anonymoose
anonymoose

Reputation: 1243

Adding a "bleed area" to canvases with fabricjs?

I'm using fabricjs (1.7.20) and would like to create a sort of "bleed area" where some space around the canvas isn't usable by the user; a sort of "wall" if you will, to stop objects from being moved to the sides of the canvas walls. How might I accomplish this?

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

canvas.add(new fabric.IText("Some text", {
  top: 25,
}));

var circle = new fabric.Circle({
  radius: 20, fill: 'green', left: 100, top: 100
});
var triangle = new fabric.Triangle({
  width: 20, height: 30, fill: 'blue', left: 150, top: 150
});

canvas.add(circle, triangle);
canvas {
  border: 1px solid #dddddd;
  margin-top: 10px;
  border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js"></script>
<canvas id="c"></canvas>


This was suggested to me and it is the closest I've gotten. I'm looking to do this, but 10px, give or take, from the border of the canvas.

canvas.on('object:moving', function (e) {
        var obj = e.target;
         // if object is too big ignore
        if(obj.currentHeight > obj.canvas.height || obj.currentWidth > obj.canvas.width){
            return;
        }        
        obj.setCoords();        
        // top-left  corner
        if(obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0){
            obj.top = Math.max(obj.top, obj.top-obj.getBoundingRect().top);
            obj.left = Math.max(obj.left, obj.left-obj.getBoundingRect().left);
        }
        // bot-right corner
        if(obj.getBoundingRect().top+obj.getBoundingRect().height  > obj.canvas.height || obj.getBoundingRect().left+obj.getBoundingRect().width  > obj.canvas.width){
            obj.top = Math.min(obj.top, obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top);
            obj.left = Math.min(obj.left, obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left);
        }
});

Upvotes: 4

Views: 1671

Answers (1)

Patrick Hund
Patrick Hund

Reputation: 20276

You can add a 10 pixel bleed area by adding / subtracting the value 10 from the conditions that determine if an object is being moved out of the “bleed” area (I'd actually prefer to call it “padding”), and adding / subtracting from the calculation that repositions the object inside the padding boundaries.

Here's an updated example that works:

var padding = 10;
var canvas = new fabric.Canvas("c");

canvas.setHeight(350);
canvas.setWidth(350);

canvas.add(new fabric.IText("Some text", {
    top: 25,
}));

var circle = new fabric.Circle({
    radius: 20,
    fill: 'green',
    left: 100,
    top: 100
});
var triangle = new fabric.Triangle({
    width: 20,
    height: 30,
    fill: 'blue',
    left: 150,
    top: 150
});

canvas.add(circle, triangle);

canvas.on('object:moving', function(e) {
    var obj = e.target;
    
    // if object is too big ignore
    if (obj.currentHeight > obj.canvas.height - padding * 2 ||
        obj.currentWidth > obj.canvas.width - padding * 2) {
        return;
    }
    obj.setCoords();

    // top-left corner
    if (obj.getBoundingRect().top < padding ||
    	obj.getBoundingRect().left < padding) {
        obj.top = Math.max(obj.top, obj.top - obj.getBoundingRect().top + padding);
        obj.left = Math.max(obj.left, obj.left - obj.getBoundingRect().left + padding);
    }
    
    // bot-right corner
    if (obj.getBoundingRect().top + obj.getBoundingRect().height > obj.canvas.height - padding || 
    	obj.getBoundingRect().left + obj.getBoundingRect().width > obj.canvas.width - padding) {
        obj.top = Math.min(
        	obj.top,
        	obj.canvas.height - obj.getBoundingRect().height + obj.top - obj.getBoundingRect().top - padding);
        obj.left = Math.min(
        	obj.left,
            obj.canvas.width - obj.getBoundingRect().width + obj.left - obj.getBoundingRect().left - padding);
    }
});
canvas {
  border: 1px solid #dddddd;
  margin-top: 10px;
  border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js"></script>
<canvas id="c"></canvas>

In the first line, I've defined a variable “padding” that refers to the desired padding size. This way, if you want to change the padding later on, you don't have to change it in eight different places.

The padding variable used instead of 0 in the condition for the top left corner.

If the “top left” condition is true, the padding is added to the calculation for repositioning the object.

In the “bottom right” part, we are doing the opposite – we subtract the padding from the condition and subtract from the repositioning calculation.

You can also try the code in this fiddle: https://jsfiddle.net/pahund/hz7jLnme/

Upvotes: 3

Related Questions