【问题标题】:How to align object by bounding box in FabricJS?如何通过 FabricJS 中的边界框对齐对象?
【发布时间】:2018-05-25 12:13:44
【问题描述】:

想知道是否可以通过边界框对齐 FabricJs 中的对象?

我正在使用 obj.getBoundingRect() 函数来确定对象边界,然后将它们与活动对象(我移动的对象)的边界框 (BB) 坐标进行比较。如果我发现某物落在某个间隙之间(比如说 10 像素),我会使用 .setTop() 属性将活动对象顶部指定为与可比较元素相同的顶部。

问题是 TOP 不是正确使用的属性,因为边界框的顶部可能因元素而异。例如,两个顶部相同但角度不同的元素将具有不同的Bounding Box Top...

希望你明白我的意思...

https://jsfiddle.net/redlive/hwcu1p4f/

var canvas = this.__canvas = new fabric.Canvas('canvas');
//fabric.Object.prototype.transparentCorners = false;

var red = new fabric.Rect({
	id: 1,
  left: 100,
  top: 50,
  width: 100,
  height: 100,
  fill: 'red',
  angle: 0,
  padding: 10
});
canvas.add(red);

var green = new fabric.Rect({
	id: 2,
  left: 250,
  top: 180,
  width: 100,
  height: 100,
  fill: 'green',
  angle: 45,
  padding: 10
});
canvas.add(green);
canvas.renderAll();

canvas.on("object:moving", function(e){
	const draggableObj = e.target;
  const draggableObjBound = draggableObj.getBoundingRect();
  
  canvas.forEachObject(function(obj) {
    if (obj.id !== draggableObj.id) {
      var bound = obj.getBoundingRect();
      if (draggableObjBound.top > bound.top - 10 && draggableObjBound.top < bound.top + 10) {
        draggableObj.setTop(obj.getTop());
      }
    }
  });
});

canvas.forEachObject(function(obj) {
  var setCoords = obj.setCoords.bind(obj);
  obj.on({
    moving: setCoords,
    scaling: setCoords,
    rotating: setCoords
  });
});

canvas.on('after:render', function() {
  canvas.contextContainer.strokeStyle = '#555';
  canvas.forEachObject(function(obj) {
    var bound = obj.getBoundingRect();
    canvas.contextContainer.strokeRect(
      bound.left,
      bound.top,
      bound.width,
      bound.height
    );
  })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-rc.3/fabric.js"></script>
<canvas id="canvas" width="800" height="500" style="border:1px solid #ccc"></canvas>

【问题讨论】:

    标签: fabricjs


    【解决方案1】:

    你应该使用中心来对齐它们,这不会改变。

    以左5对齐边界框为例:

    1) 计算边界框。 2) 考虑中心,将对象的位置设置为 5 + bb.width/2。

    在这种情况下,边界矩形对齐。

    var canvas = this.__canvas = new fabric.Canvas('canvas');
    //fabric.Object.prototype.transparentCorners = false;
    
    var red = new fabric.Rect({
    	id: 1,
      left: 100,
      top: 50,
      width: 100,
      height: 100,
      fill: 'red',
      angle: 0,
      padding: 10
    });
    canvas.add(red);
    
    var green = new fabric.Rect({
    	id: 2,
      left: 250,
      top: 180,
      width: 100,
      height: 100,
      fill: 'green',
      angle: 45,
      padding: 10
    });
    canvas.add(green);
    
    //ALIGN EVERYTHING TO 5
    canvas.forEachObject(function(object) {
      var bb = object.getBoundingRect();
      object.setPositionByOrigin({ x: 5 + bb.width/2, y: bb.top }, 'center', 'center');
      object.setCoords();
    });
    
    
    canvas.renderAll();
    
    
    canvas.on("object:moving", function(e){
    	const draggableObj = e.target;
      const draggableObjBound = draggableObj.getBoundingRect(true, true);
      
      canvas.forEachObject(function(obj) {
        if (obj.id !== draggableObj.id) {
          var bound = obj.getBoundingRect(true, true);
          if (draggableObjBound.top > bound.top - 10 && draggableObjBound.top < bound.top + 10) {
            draggableObj.setPositionByOrigin({ x: draggableObj.left, y: bound.top + draggableObjBound.height/2 }, draggableObj.originX, 'center');
          }
        }
      });
    });
    
    canvas.forEachObject(function(obj) {
      var setCoords = obj.setCoords.bind(obj);
      obj.on({
        moving: setCoords,
        scaling: setCoords,
        rotating: setCoords
      });
    });
    
    canvas.on('after:render', function() {
      canvas.contextContainer.strokeStyle = '#555';
      canvas.forEachObject(function(obj) {
        var bound = obj.getBoundingRect(true, true);
        canvas.contextContainer.strokeRect(
          bound.left,
          bound.top,
          bound.width,
          bound.height
        );
      })
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-rc.3/fabric.js"></script>
    <canvas id="canvas" width="800" height="500" style="border:1px solid #ccc"></canvas>

    【讨论】:

    • 抛出错误 obj.getTop is not a function 和相同的 draggableObj.setTop is not a function
    • 投掷的和原来的小提琴一样多。代码的目的是添加对齐部分。你认为我应该解决这一切吗?我可以...
    • 抱歉,2.0的bug,set/get方法不能正常工作
    • 不是bug setTop,getTop 和其他在2.0 中是可选的。你必须明确要求他们
    • @AndreaBogazzi 谢谢你的代码。我没明白 //ALIGN EVERYTHING TO 5 代表什么?什么是5?我需要将唯一的 DRAGGABLE 对象与其余对象对齐...
    猜你喜欢
    • 2017-05-01
    • 2019-10-03
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 2021-05-03
    • 2020-04-08
    • 2018-10-07
    相关资源
    最近更新 更多