Подождите, пока изображение загрузится, прежде чем продолжить - PullRequest
31 голосов
/ 27 декабря 2011

Я разрабатываю игру с использованием JavaScript и canvas.По мере загрузки игры все изображения, которые будут использоваться, кэшируются.

Наблюдая временную шкалу ресурса, я вижу, что следующий код запускает асинхронный запрос:

var sprite = new Image();
sprite.src = "sprites/sheet1.png";

Движок будет работатьвыполнение, в конце концов начинает рисовать и играть на уровне.Изображения, которые загружаются после того, как нарисован первый кадр, могут никогда не появиться из-за обрезки (то есть, не «испачкаться»).

Итак, я проверил следующее:

console.log("begin");
var sprite = new Image();
sprite.onload = function() { console.log('loaded!'); };
sprite.src = "sprites/sheet1.png";
console.log("end");

Полученные результаты консолив порядке их появления:

  • begin
  • end
  • loaded!

Я ищуаналогично $.ajax с async: false для выполнения загрузки.Не могу понять, как ... заранее спасибо за помощь!J.

Ответы [ 3 ]

60 голосов
/ 27 декабря 2011

Вы не должны делать ничего синхронного (даже AJAX) вызовов, вместо этого просто поместите свой код в соответствующий обратный вызов:

function loadSprite(src, callback) {
    var sprite = new Image();
    sprite.onload = callback;
    sprite.src = src;
}

Тогда используйте это так:

loadSprite('sprites/sheet1.png', function() {
    // code to be executed later
});

Если вы хотите передать дополнительные аргументы, вы можете сделать это следующим образом:

sprite.onload = function() {
    callback(whatever, args, you, have);
};

Если вы хотите загрузить несколько элементов и хотите дождаться завершения всех из них, рассмотрите возможность использования объекта jQuery deferred :

function loadSprite(src) {
    var deferred = $.Deferred();
    var sprite = new Image();
    sprite.onload = function() {
        deferred.resolve();
    };
    sprite.src = src;
    return deferred.promise();
}

В функции загрузки спрайтов вы делаете что-то вроде этого:

var loaders = [];
loaders.push(loadSprite('1.png'));
loaders.push(loadSprite('2.png'));
loaders.push(loadSprite('3.png'));
$.when.apply(null, loaders).done(function() {
    // callback when everything was loaded
});

http://api.jquery.com/jQuery.when/

2 голосов
/ 22 сентября 2013

Этот вопрос старый, но есть способ сделать это, не требуя jquery ИЛИ замораживания браузера.

В image1.onLoad загрузите image2.В image2.onLoad, загрузите image3.В image3.onLoad загрузите image4.....В изображении n .onLoad загрузите вашу основную функцию.

Я не уверен, что это ЛУЧШИЙ способ сделать это, но это лучше, чем заморозить браузер, по крайней мере,Вы также можете загрузить все свои аудиофайлы или любые другие ресурсы, которые вам нужны, или любой другой javascript, который вам нужен для запуска.

Замораживание браузера не требуется

0 голосов
/ 01 сентября 2014

У меня есть эта проблема с холстом Я попробовал ваше решение, но лучший и простой способ, который работает:

function COLPOinitCanvas(imagesfile) {
    COLPOcanvas = document.getElementById("COLPOcanvas");
    COLPOctx = COLPOcanvas.getContext("2d");
    var imageObj = new Image();
    imageObj.src = imagesfile;
    imageObj.onload = function () {
        COLPOctx.drawImage(imageObj, 0, 0, COLPOcanvas.width, COLPOcanvas.height);
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...