等待圖像加載后再繼續

[英]Wait for image to be loaded before going on


I'm developing a game using JavaScript and canvas. As the game loads, all images that will be used are being cached.

我正在使用JavaScript和canvas開發游戲。隨着游戲加載,將使用所有將要使用的圖像。

Observing the resource timeline, I see that the following code triggers an asynchronous request:

觀察資源時間線,我看到以下代碼觸發異步請求:

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

The engine will keep executing, eventually beginning to draw and play the level. Images that are loaded after the first frame is painted might never appear due to clipping (i.e. not getting "dirty").

引擎將繼續執行,最終開始繪制並播放關卡。繪制第一幀后加載的圖像可能永遠不會因剪裁而出現(即不會變得“臟”)。

So I tested the following:

所以我測試了以下內容:

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

The resulting console outputs in the order they occur are:

生成的控制台按順序輸出的輸出是:

  • begin
  • end
  • loaded!

I'm looking for a similar way to $.ajax with async: false to perform the loading. Can't figure out how... thanks in advance for you help! J.

我正在尋找與$ .ajax類似的方法,使用async:false來執行加載。無法弄清楚如何...提前感謝您的幫助! J.

3 个解决方案

#1


59  

You shouldn't make anything synchronous (not even AJAX) calls but instead simply put your code in the appropriate callback:

您不應該進行任何同步(甚至不是AJAX)調用,而只需將代碼放在適當的回調中:

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

Then use it like this:

然后像這樣使用它:

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

If you want to pass additional arguments, you can do it like this:

如果要傳遞其他參數,可以這樣做:

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

If you want to load multiple elements and need to wait for all of them to finish, consider using the jQuery deferred object:

如果要加載多個元素並需要等待所有元素完成,請考慮使用jQuery延遲對象:

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

In the function loading the sprites, you do something like this:

在加載sprite的函數中,你可以這樣做:

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


2  

This question is old, but there is a way to do this without requiring jquery, OR freezing the browser.

這個問題很老,但有一種方法可以在不需要jquery的情況下執行此操作,或凍結瀏覽器。

In image1.onLoad, make it load image2.
In image2.onLoad, make it load image3.
In image3.onLoad, make it load image4.
....
In imagen.onLoad make it load your main function.

在image1.onLoad中,使其加載image2。在image2.onLoad中,使其加載image3。在image3.onLoad中,使其加載image4。 ....在imagen.onLoad中使它加載你的主函數。

I'm not sure if this is the entirely BEST way to do it, but it's better than freezing the browser, at least.
You are able to also load all of your audio files or whatever other resources you need, or any other javascript you need to run.

我不確定這是否是完全最好的方法,但它至少比凍結瀏覽器更好。您還可以加載所有音頻文件或您需要的任何其他資源,或者您需要運行的任何其他JavaScript。

Freezing the browser is not required

不需要凍結瀏覽器

#3


0  

I've this problem with canvas i tried your solution but a best and simple way that works is:

我用canvas的這個問題我試過你的解決方案,但最好和最簡單的方法是:

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);
    };
}

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2011/12/27/7299376f9f49c4946375a2c60ff04e0d.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com