25

在fabricjs中,我想创建一个场景,其中鼠标下的对象在z-index中上升到场景的顶部,然后一旦鼠标离开该对象,它就会回到它来自的z-index。一个人不能设置 object.zindex (这会很好)。相反,我使用了一个占位符对象,该对象被放入对象列表中的旧位置,然后使用 canvas.insertAt 将旧对象放回它在列表中的位置。但是,这是行不通的。

有关此状态,请参阅http://jsfiddle.net/rFSEV/ 。

var canvasS = new fabric.Canvas('canvasS', { renderOnAddition: false, hoverCursor: 'pointer', selection: false });
var bars = {}; //storage for bars (bar number indexed by group object)
var selectedBar = null; //selected bar (group object)
var placeholder = new fabric.Text("XXXXX", { fontSize: 12 });

//pass null or a bar
function selectBar(bar) {
    if (selectedBar) {
        //remove the old topmost bar and put it back in the right zindex
        //PROBLEM: It doesn't go back; it stays at the same zindex
        selectedBar.remove();
        canvasS.insertAt(selectedBar, selectedBar.XZIndex, true);
        selectedBar = null;
        }
    if (bar) {
        //put a placeholder object ("XXX" for now) in the position
        //where the bar was, and put the bar in the top position
        //so it shows topmost
        selectedBar = bar;
        canvasS.insertAt(placeholder, selectedBar.XZIndex, true);
        canvasS.add(bar);
        canvasS.renderAll();
        }
    }

canvasS.on({
     'mouse:move': function(e) {
        //hook up dynamic zorder
        if (!e.target) return;
        if (bars[e.target])
            selectBar(e.target);
        else
            selectBar(null);
        },
    });

var objcount = canvasS.getObjects().length;

//create bars
for (var i = 0; i < 20; ++i) {
    var rect = new fabric.Rect({
      left: 0,
      top: 0,
      rx: 3,
      ry: 3,
      stroke: 'red',
      width: 200,
      height: 25
    });
    rect.setGradientFill({
      x1: 0,
      y1: 0,
      x2: 0,
      y2: rect.height,
      colorStops: {
        0: '#080',
        1: '#fff'
      }
    });    
    var text = new fabric.Text("Bar number " + (i+1), {
        fontSize: 12
    });
    var group = new fabric.Group([ rect, text ], {
      left: i + 101,
      top: i * 4 + 26
    });
    group.hasControls = group.hasBorders = false;

    //our properties (not part of fabric)
    group.XBar = rect;
    group.XZIndex = objcount++;

    canvasS.add(group);
    bars[group] = i;
    }
canvasS.renderAll();
4

5 回答 5

36

从 fabric.js 版本 1.1.4 开始,可以使用一种新的 zIndex 操作方法:

canvas.moveTo(object, index);
object.moveTo(index);

我认为这对您的用例很有帮助。我已经更新了你的 jsfiddle - 我希望这是你想要的:
jsfiddle

于 2013-04-29T09:24:09.353 回答
10

Also make sure you change z-index AFTER adding object to canvas.

So code will looks like:

canvas.add(object);
canvas.moveTo(object, index);

Otherwise fabricjs don`t care about z-indexes you setup.

于 2014-10-29T09:25:15.827 回答
3

添加线条对象后,我使用以下方法使线条出现在对象下方:

canvas.add(line);
canvas.sendToBack(line);

其他选项是

  • canvas.sendBackwards
  • canvas.sendToBack
  • canvas.bringForward
  • canvas.bringToFront

见: https ://github.com/fabricjs/fabric.js/issues/135

于 2019-05-30T19:08:50.430 回答
0

您可以修改您的_chooseObjectsToRender方法以在其末尾进行以下更改,您将能够实现 css-style zIndexing。

objsToRender = objsToRender.sort(function(a, b) {
  var sortValue = 0, az = a.zIndex || 0, bz = b.zIndex || 0;

  if (az < bz) {
    sortValue = -1;
  }
  else if (az > bz) {
    sortValue = 1;
  }

  return sortValue;
});

https://github.com/fabricjs/fabric.js/pull/5088/files

于 2018-07-05T21:44:40.570 回答
0

您可以使用这两个函数来获取结构对象的 z-index 并修改对象的 z-index,因为没有特定的方法可以通过 object index 修改 z-index:

fabric.Object.prototype.getZIndex = function() {
    return this.canvas.getObjects().indexOf(this);
}

fabric.Canvas.prototype.moveToLayer = function(object,position) {
    while(object.getZIndex() > position) {
        this.sendBackwards(object);
    }
}
于 2020-05-14T16:33:18.747 回答