Fabric.js - проблема с нанесением нескольких изображений zindex

Я использую этот скрипт:

var canvas = new fabric.Canvas('game_canvas', { selection: false });

fabric.Image.fromURL('images/bg.jpg', function(img) {
  img.set('left', 1024/2).set('top', 600/2).set('zindex', 0);
  canvas.add(img);        
});

fabric.Image.fromURL('images/panel-2-bg-l-r.png', function(img) {
  img.set('left', 262/2).set('top', (390/2)+110).set('zindex', 1);
  canvas.add(img);        
});

fabric.Image.fromURL('images/player-board.png', function(img) {
  img.set('left', 254/2).set('top', (122/2)).set('zindex', 2);
  canvas.add(img);        
});

fabric.Image.fromURL('images/player-board-top-red.png', function(img) {
  img.set('left', 203/2).set('top', (109/2)).set('zindex', 3);
  canvas.add(img).bringToFront(img);          
});

3-е изображение работает правильно и показывает один поверх другого. Но если я добавлю 4-й, он прячется за 3-м. Если я укажу zindex для изображения, оно все равно будет только под третьим.

Что не так с этим? Я что-то здесь не так делаю? Пожалуйста помоги.

Спасибо
Питер

2 ответа

Решение

Здесь есть пара вопросов.

1) Вы не можете изменить zindex изображений, установив их свойство zindex. Изображения ткани просто не имеют такого свойства, и изменение его не приводит к изменению индекса изображения на холсте. Это делает все те .set('zindex', 0), .set('zindex', 1)и т. д. в значительной степени неоперативный.

2) bringToFront здесь работает как положено, в результате чего последнее изображение доходит до вершины стека рисования. Но проблема в том, что изображение "images/player-board-top-red.png", которое вы загружаете последним, не обязательно будет последним добавленным. Эти 4 запроса являются асинхронными; они идут в любом порядке, поэтому обратные вызовы выполняются также в любом порядке. Например, в моем тесте последнее изображение идет вторым, выполняется обратный вызов, изображение выводится на передний план, но затем "перезаписывается" с помощью следующих 2 обратных вызовов.

Как сделать так, чтобы последнее изображение отображалось сверху? Что ж, мы можем просто проверить, что все изображения загружены, прежде чем пытаться вывести последнее наверх:

var img4;
// ...
function checkAllLoaded() {
  if (canvas.getObjects().length === 4) {
    canvas.bringToFront(img4);
  }
}
// ...
fabric.Image.fromURL('images/1.png', function(img) {
  img.set('left', 0).set('top', 0);
  canvas.add(img);
  checkAllLoaded(img);
});
// load other images, making sure to include `checkAllLoaded` in callback
fabric.Image.fromURL('images/4.png', function(img) {
  img4 = img.set('left', 0).set('top', 0);
  canvas.add(img);
  checkAllLoaded(img);
});

Кстати, не забывайте, что вы можете передать объект set метод вроде так:

img.set({ left: ..., top: ... });

И с тех пор set является цепным и возвращает ссылку на экземпляр, вы даже можете передать его add вот так:

canvas.add(img.set({ left: ..., top: ... }));

Надеюсь это поможет.

Ты можешь использовать canvas.insertAt(object,index); вместо canvas.add(object) установить zIndex объекта по вашему выбору.

Также вы можете получить любой объект, используя:

canvas_object = canvas.item(index);

Если вы хотите вывести этот объект вперед, используйте:

canvas_object.bringForward() 

//or

canvas_object.bringToFront() 
Другие вопросы по тегам