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()