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

Lee*_*lor 2 javascript fabricjs

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

  1. 通过拖动来选择两个方块。
  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();
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

And*_*zzi 5

这是否可以被视为错误,取决于您期望该函数执行什么操作。

该功能的文档说: 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();
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)