Fabric Constain Movement with Padding

https://stackoverflow.com/questions/47870309/adding-a-bleed-area-to-canvases-with-fabricjs

by Patrick Hund

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.21/fabric.min.js"></script>
<canvas id="c" width="400" height="400"></canvas>

CSS

canvas {
    border: 1px solid #dddddd;
    margin-top: 10px;
    border-radius: 3px;
}

JavaScript

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

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);
    }
});