Почему последовательность zIndex моих объектов не соответствует ожиданиям? - PullRequest
0 голосов
/ 28 января 2019

Как я могу получить список всех объектов со всеми параметрами (x, y, width и т. Д.), Включая параметр 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';

Изображение3 имеет индекс = 1, но больше изображения2, которое имеет индекс = 2.

1 Ответ

0 голосов
/ 28 января 2019

Во-первых, в ответ на комментарий @ lavrton, вы должны добавить konva.Image к холсту, как только вы его создадите, а не в событии загрузки изображения.Объекты изображения не являются накладными расходами на холст, и вы можете быть уверены в начальной последовательности z-index.После этого вы можете изменить последовательность, но, по крайней мере, вы начнете с известного макета.

И, как правило, вам нужно соблюдать осторожность при использовании любых команд внутри события onload изображения.Загрузка изображения является асинхронной - это означает, что она не происходит в той последовательности, которую вы могли бы ожидать при написании кода.Большое изображение, полученное с медленного сервера, будет загружаться медленнее, чем маленькое изображение с быстрого сервера, но вы не можете делать какие-либо предположения относительно последовательности.ЕДИНСТВЕННЫЙ способ гарантировать, что последовательность должна инициировать загрузку второго изображения из события onload первого, но обычно это приводит к неправильному UX.

Вернемся к опубликованному коду,код в моем фрагменте ниже будет работать так, как вы хотели.Я переключил константу ECMA2015 на простые старые переменные и удалил ненужные преобразования.

Я также добавил некоторый код для анализа результатов, показывая ожидаемое значение zIndex и достигнутые значения zIndex.

Обратите внимание, что значение zIndex в Konva относительно родительского контейнера, а не абсолютное.Так, например, когда я устанавливаю 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>
...