添加"出血区域"用fabricjs画布?

时间:2017-12-18 14:14:04

标签: javascript canvas fabricjs

我正在使用fabricjs(1.7.20)并想创建一种"出血区域"用户无法使用画布周围的某些空间;一种"墙"如果你愿意,阻止物体移动到画布墙的两侧。我怎么能做到这一点?



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>
&#13;
&#13;
&#13;

这是向我建议的,它是我得到的最接近的。我希望这样做,但是10px,给予或采取从画布的边界。

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

1 个答案:

答案 0 :(得分:3)

您可以通过在确定对象是否被移出“出血”区域的条件中添加/减去值10来添加10像素出血区域(我实际上更喜欢将其称为“填充” ),并在计算中添加/减去重新定位填充边界内的对象。

这是一个有效的更新示例:

&#13;
&#13;
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);
    }
});
&#13;
canvas {
  border: 1px solid #dddddd;
  margin-top: 10px;
  border-radius: 3px;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js"></script>
<canvas id="c"></canvas>
&#13;
&#13;
&#13;

在第一行中,我定义了一个变量“padding”,它指的是所需的填充大小。这样,如果您想稍后更改填充,则不必在八个不同的位置更改它。

在左上角的条件中使用填充变量而不是0。

如果“左上角”条件为真,则将填充添加到计算中以重新定位对象。

在“右下角”部分,我们正在相反 - 我们从条件中减去填充并从重新定位计算中减去。

你也可以尝试这个小提琴中的代码:https://jsfiddle.net/pahund/hz7jLnme/