向前发送多个对象会改变它们的顺序(z-index)

时间:2017-02-17 01:31:18

标签: javascript fabricjs

以下代码段在红色正方形上方有一个绿色正方形

  1. 通过拖动它们来选择两个方块。
  2. 点击bring forward按钮
  3. 点击bring forward后,方块已切换顺序。我的理解是,项目应保持相同的顺序,但随着按钮被进一步点击,它们会越来越高于其他未选择的项目。

    如果您取消选择并重复实验,您会看到它们再次切换。

    有什么想法吗?

    
    
    var canvas = new fabric.Canvas('c', 
    {
      preserveObjectStacking	: true
    });
    
    var rect = new fabric.Rect({
      left: 10, top: 10,
      fill: 'red',
      width: 100, height: 100,
      hasControls: true
    });
    
    canvas.add(rect);
    
    var rect2 = new fabric.Rect({
      left: 40, top: 40,
      fill: 'green',
      width: 100, height: 100,
      hasControls: true
    });
    
    canvas.add(rect2);
    
    $("#bringForward").click(function()
    {
    	var items = canvas.getActiveObject() || canvas.getActiveGroup();
    
    	if(items)
    		items.bringForward();
    });
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.6/fabric.min.js"></script>
    <button id="bringForward">Bring Forward</button>
    
    <canvas id="c" width="640" height="480"></canvas>
    &#13;
    &#13;
    &#13;

1 个答案:

答案 0 :(得分:4)

这可以被视为一个或多个错误,具体取决于您对该功能的期望。

该功能的文档说: Moves an object or a selection up in stack of drawn objects 实际上是这样做的。 顶部的物体不能更多地位于顶部,下面的物体可以继续下去。

对于开发者而言,这可能看起来像一种奇怪的行为,对我而言并非如此。但猜测是个人的。

这是您的小部件,其中包含经过修改的代码段,可以尝试更好的解决方案。

var removeFromArray = fabric.util.removeFromArray;

// modified function to avoid snapping
fabric.StaticCanvas.prototype.bringForward = function (object, intersecting) {
      if (!object) {
        return this;
      }
      var activeGroup = this._activeGroup,
          i, obj, idx, newIdx, objs, latestIndex;

      if (object === activeGroup) {
        objs = activeGroup._objects;
        latestIndex = this._objects.length;
        for (i = objs.length; i--;) {
          obj = objs[i];
          idx = this._objects.indexOf(obj);
          if (idx !== this._objects.length - 1 && idx < latestIndex - 1) {
            newIdx = idx + 1;
            latestIndex = newIdx;
            removeFromArray(this._objects, obj);
            this._objects.splice(newIdx, 0, obj);
          } else {
            latestIndex = idx;
          }
        }
      }
      else {
        idx = this._objects.indexOf(object);
        if (idx !== this._objects.length - 1) {
          // if object is not on top of stack (last item in an array)
          newIdx = this._findNewUpperIndex(object, idx, intersecting);
          removeFromArray(this._objects, object);
          this._objects.splice(newIdx, 0, object);
        }
      }
      this.renderAll && this.renderAll();
      return this;
    };


var canvas = new fabric.Canvas('c', 
{
  preserveObjectStacking	: true
});

var rect = new fabric.Rect({
  left: 10, top: 10,
  fill: 'red',
  width: 100, height: 100,
  hasControls: true
});

canvas.add(rect);

var rect2 = new fabric.Rect({
  left: 40, top: 40,
  fill: 'green',
  width: 100, height: 100,
  hasControls: true
});

canvas.add(rect2);

var rect3 = new fabric.Rect({
  left: 70, top: 70,
  fill: 'blue',
  width: 100, height: 100,
  hasControls: true
});

canvas.add(rect3);

var rect4 = new fabric.Rect({
  left: 100, top: 100,
  fill: 'orange',
  width: 100, height: 100,
  hasControls: true
});

canvas.add(rect4);

$("#bringForward").click(function()
{
	var items = canvas.getActiveObject() || canvas.getActiveGroup();

	if(items)
		items.bringForward();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.6/fabric.min.js"></script>
<button id="bringForward">Bring Forward</button>

<canvas id="c" width="640" height="480"></canvas>