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

Sending multiple objects forward changes their order (z-index)

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

  1. Select 拖动两个方块。
  2. 单击 bring forward 按钮

点击 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>

这可以被认为是错误或不是错误,具体取决于您希望该功能做什么。

该功能的文档说: 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>