为什么我的对象的zIndex序列不是我期望的?

时间:2019-01-28 09:42:15

标签: konvajs

如何在完成调整大小后在舞台上获取具有所有参数(x,y,宽度等)的所有对象的列表,包括zIndex参数?创建舞台时,如何为每个对象设置zIndex?

我有此代码,但是setZIndex无法正常工作。图片设置不正确。

const oKonvaStage = new Konva.Stage({
    container: 'dropzone'
});

const oKonvaLayer = new Konva.Layer();
oKonvaStage.add(oKonvaLayer);

const oKonvaImage1 = new Konva.Image({
    x: 624,
    y: 433,
    width: 1920,
    height: 1280
});

const oImage1 = new Image();
oImage1.onload = function() {
    oKonvaImage1.image(oImage1);
    oKonvaLayer.add(oKonvaImage1);
    oKonvaImage1.setZIndex(2);
    oKonvaLayer.draw();
};

oImage1.src = 'image1.jpg';

oKonvaImage1.on('transformend', function(e) {
    UpdateAttrs();
});

const oKonvaImage2 = new Konva.Image({
    x: 9,
    y: 254,
    width: 1024,
    height: 1024
});

const oImage2 = new Image();
oImage2.onload = function() {
    oKonvaImage2.image(oImage2);
    oKonvaLayer.add(oKonvaImage2);
    oKonvaImage2.setZIndex(0);
    oKonvaLayer.draw();
};

oImage2.src = 'image2.jpg';

oKonvaImage2.on('transformend', function(e) {
    UpdateAttrs();
});

const oKonvaImage3 = new Konva.Image({
    x: -586,
    y: -315,
    width: 1920,
    height: 1199
});

const oImage3 = new Image();
oImage3.onload = function() {
    oKonvaImage3.image(oImage3);
    oKonvaLayer.add(oKonvaImage3);
    oKonvaImage3.setZIndex(1);
    oKonvaLayer.draw();
};

oImage3.src = 'image3.jpg';

Image3的索引为1,但在Image2的索引为2之上。

1 个答案:

答案 0 :(得分:1)

首先,在@lavrton的评论提示下,您应该在实例化konva.Image之后将其添加到画布上-不在image onload事件中。图像对象在画布上没有开销,因此您可以确定初始的z-index序列。之后,您可以更改顺序,但至少要从已知的布局开始。

作为一般规则,在图像的onload事件内使用任何命令时都需要小心。图像加载是异步的-意味着它不会按照编写代码时可能发生的顺序发生。来自慢速服务器的大图像将比来自快速服务器的小图像加载更慢,但是您不能对序列进行任何假设。确保序列的唯一方法是从第一个映像的onload事件启动第二个映像的加载,但这通常会导致不良的UX。

回到您发布的代码,下面我的代码段中的代码似乎可以正常工作。我将ECMA2015 const切换为普通的旧var,并删除了不必要的on-transforms。

我还添加了一些代码来分析结果,显示了希望的zIndex值和已实现的zIndex值。

请注意,Konva中的zIndex值是相对于父容器而不是绝对的。  因此,例如,当我设置zondex = 999时,我实际上得到的值为4。

摘要:

  • 避免在上载事件中调用对序列至关重要的代码。
  • 不要期望得到您想要的zindex。

var div = $('#dropzone');
var oKonvaStage = new Konva.Stage({container: 'dropzone', width: div.width(), height: div.height()});

var indexWanted = [];

   
var oKonvaLayer = new Konva.Layer();
oKonvaStage.add(oKonvaLayer);

var oKonvaImage1 = new Konva.Image({
    name: 'image-1',
    x: 20,
    y: 20,
    width: 300,
    height: 100
});

var oImage1 = new Image();
oImage1.onload = function() {
    oKonvaLayer.add(oKonvaImage1);
    oKonvaImage1.image(oImage1);
    oKonvaImage1.setZIndex(2);
    indexWanted[0] = 2;
    oKonvaLayer.draw();
    sayPos();
};

oImage1.src = 'https://dummyimage.com/300x100/666/fff.png?text=Image-1'


var oKonvaImage2 = new Konva.Image({
    name: 'image-2',
    x: 10,
    y: 100,
    width: 300,
    height: 100
});

var oImage2 = new Image();
oImage2.onload = function() {
    oKonvaImage2.image(oImage2);
    oKonvaLayer.add(oKonvaImage2);
    oKonvaImage2.setZIndex(0);
    indexWanted[1] = 0;
    oKonvaLayer.draw();
    sayPos();
};

oImage2.src = 'https://dummyimage.com/300x100/333/fff.png?text=Image-2';

var oKonvaImage3 = new Konva.Image({
    name: 'image-3',
    x: 280,
    y: 80,
    width: 300,
    height: 100
});

var oImage3 = new Image();
oImage3.onload = function() {
    oKonvaImage3.image(oImage3);
    oKonvaLayer.add(oKonvaImage3);
    oKonvaImage3.setZIndex(999);  //  <<<< notice this is set to 99. Compare to console output !!
    indexWanted[2] = 999;
    oKonvaLayer.draw();
    sayPos();
};

oImage3.src = 'https://dummyimage.com/300x100/ccc/fff.png?text=Image-3';

oKonvaLayer.draw();
oKonvaStage.draw();

var picCnt = 0, s= '', imgNo = 0;
function sayPos(){
  picCnt = picCnt + 1;
  if (picCnt === 3){
    for (var i = 0; i < indexWanted.length; i = i + 1){
      imgNo = i + 1;
      s = s + '<br/>Image-' + imgNo + ' zindex wanted = ' + indexWanted[i]  + ' actual zIndex=' +   oKonvaLayer.findOne('.image-' + imgNo).getAbsoluteZIndex();
    }
  $('#info').html(s)

    
  }

}
#info {
font-size: 10pt;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.min.js"></script>
<p id='info' >
</p>
<div id='dropzone' style="position: absolute; top: 90px; z-index: -1; display: inline-block; left: 0px;  width: 600px; height: 400px; background-color: silver;"></div>