在继续之前等待图像加载
Posted
技术标签:
【中文标题】在继续之前等待图像加载【英文标题】:Wait for image to be loaded before going on 【发布时间】:2012-01-28 12:43:57 【问题描述】:我正在使用 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.
【问题讨论】:
【参考方案1】:您不应该进行任何同步(甚至是 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/
【讨论】:
感谢您的回复。我忘了提一下,这段代码是由父级调用的函数名“loadSprite(name)”的一部分。该父级从“for each sprite loadSprite(name)”之类的循环中调用它。我需要能够中断处理,导致该方法仅在加载图像时返回。有什么想法吗? 如果不冻结浏览器,您将无法执行此操作。我将更新我的答案以显示(该)正确的解决方案。 嘿,谢谢,这很有趣。我根本不知道那个延迟对象! 这是一个很好的解释,说明了如何以没有已延迟对象(如 $.ajax)的方式使用 Deferred 对象,并且不与动画结合使用。非常有用且解释得很好 - 谢谢。【参考方案2】:这个问题很老,但是有一种方法可以做到这一点,而不需要 jquery,或者冻结浏览器。
在image1.onLoad中,让它加载image2。 在 image2.onLoad 中,使其加载 image3。 在 image3.onLoad 中,使其加载 image4。 .... 在 imagen.onLoad 中让它加载你的 main 函数。
我不确定这是否是最好的方法,但至少比冻结浏览器要好。 您还可以加载所有音频文件或您需要的任何其他资源,或您需要运行的任何其他 javascript。
不需要冻结浏览器
【讨论】:
这就是我目前的做法(第一个晚上使用 Canvas),但看起来很乱。有更好的方法吗?我已经尝试为加载的资源设置真/假标志并使用 do/while 循环,但除了这种方法之外,我什么也做不了。 不确定。我的项目只需要一两个资源,所以我从来没有进入整个资源加载场景。我确信有更好的方法来做到这一点。祝你好运! :) 我最终构建了一个自定义回调方法,该方法增加了资源计数器(并将其与资源数组的长度进行了比较),如果它们是不同的值,则要么不执行任何操作,要么开始在画布上绘制,如果值匹配(这意味着所有资源都已加载)。【参考方案3】:我的画布有这个问题 我尝试了您的解决方案,但一种最佳且简单的方法是:
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);
;
【讨论】:
以上是关于在继续之前等待图像加载的主要内容,如果未能解决你的问题,请参考以下文章