我用一个执行类似于以下功能的函数绘制了几个图像:
context.drawImage(img, width / 2 * (-1), height / 2 * (-1), width, height);
我已经读过,我需要等待图像加载才可以绘制它,如下所示:
img.onload = function() {
context.drawImage(img, width / 2 * (-1), height / 2 * (-1), width, height);
};
然而,这会导致图像被绘制,但之后,由于我每隔几毫秒调用一次绘制函数,因此它不会被绘制,因为它是简单游戏的“动画”循环的一部分。
在我的init()函数中继续运行代码之前,有没有办法可以等待onload事件?
我想这样的事情:
var image_loaded = false;
img.onload = function() {
image_loaded = true;
};
if(image_loaded) {
animate();
}
应该工作吗?除非我需要添加一个timeOut函数来继续调用init()直到image_loaded为真?
答案 0 :(得分:4)
<强> Live Demo 强>
var imagesLoaded = [],
images = [
'http://www.zombiegames.net/inc/screenshots/The-Last-Stand-Union-City.png',
'http://www.zombiegames.net/inc/screenshots/Lab-of-the-Dead.png',
'http://www.zombiegames.net/inc/screenshots/Zombotron.png',
'http://www.zombiegames.net/inc/screenshots/Road-of-the-Dead.png'],
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = 640;
canvas.height = 480;
function init(){
// just loops through the images.
if(imagesLoaded.length > 0){
ctx.drawImage(imagesLoaded[0], 0, 0, 640, 480);
imagesLoaded.push(imagesLoaded.shift());
}
setTimeout(init,500);
}
function preload(){
for(var i = 0; i < images.length; i++){
(function(value){
return function(){
var loadedImage = new Image();
loadedImage.src = images[value];
loadedImage.onload = function(){
imagesLoaded.push(loadedImage);
}
}();
})(i);
}
checkLoaded();
}
function checkLoaded(){
if(imagesLoaded.length === images.length){
console.log(imagesLoaded.length);
init();
} else{
setTimeout(checkLoaded,30);
}
}
preload();
以上是如何预加载图像并等待其他任何操作的示例。基本上,您所做的是将所有图像放在一个数组中,并将onload
事件添加到每个图像中。当他们将我通过它们加载到另一个包含所有加载图像的数组中。一旦两个阵列的长度匹配,所有图像都可以使用。
另一种方法是在加载计数器时递增计数器,并根据数组的长度检查其值。当计数器变量等于图像数组的长度时,意味着它们已经全部加载并准备好使用。
答案 1 :(得分:3)
我创建了一个简单的小型库,可以轻松加载图像。
请参阅下面的库代码:
// Simple Image Loader Library
window.Loader = (function () {
var imageCount = 0;
var loading = false;
var total = 0;
// this object will hold all image references
var images = {};
// user defined callback, called each time an image is loaded (if it is not defined the empty function wil be called)
function onProgressUpdate() {};
// user defined callback, called when all images are loaded (if it is not defined the empty function wil be called)
function onComplete() {};
function onLoadImage(name) {
++imageCount;
console.log(name + " loaded");
// call the user defined callback when an image is loaded
onProgressUpdate();
// check if all images are loaded
if (imageCount == total) {
loading = false;
console.log("Load complete.");
onComplete();
}
};
function onImageError(e) {
console.log("Error on loading the image: " + e.srcElement);
}
function loadImage(name, src) {
try {
images[name] = new Image();
images[name].onload = function () {
onLoadImage(name);
};
images[name].onerror = onImageError;
images[name].src = src;
} catch (e) {
console.log(e.message);
}
}
function getImage(/**String*/ name){
if(images[name]){
return (images[name]);
}
else{
return undefined;
}
}
// pre-load all the images and call the onComplete callback when all images are loaded
// optionaly set the onProgressUpdate callback to be called each time an image is loaded (useful for loading screens)
function preload( /**Array*/ _images, /**Callback*/ _onComplete, /**Callback <optional>*/ _onProgressUpdate) {
if (!loading) {
console.log("Loading...");
loading = true;
try {
total = _images.length;
onProgressUpdate = _onProgressUpdate || (function(){});
onComplete = _onComplete || (function(){});
for (var i = 0; i < _images.length; ++i) {
loadImage(_images[i].name, _images[i].src);
}
} catch (e) {
console.log(e.message);
}
} else {
throw new Error("Acess denied: Cannot call the load function while there are remaining images to load.");
}
}
// percentage of progress
function getProgress() {
return (imageCount / total)*100;
};
// return only the public stuff to create our Loader object
return {
preload: preload,
getProgress: getProgress,
getImage: getImage,
images: images // have access to the array of images might be useful but is not necessary
};
})();
为了确保图片已加载并且应用程序可以使用它们,库具有Loader.preload
方法。
preload方法将接收一个对象数组,每个对象包含要加载的图像的名称和src属性。您可以选择设置onComplete
回调(在加载所有图像时调用)和onProgressUpdate
回调(每次加载图像时调用)。如果要为应用程序创建加载屏幕,onProgressUpdate
回调非常有用。
使用Loader.getProgress()
获取随时加载的图像百分比。
要获取已加载图像的引用,请调用Loader.getImage(name)
,其中name是图像的名称属性(String)。
如果由于某种原因需要迭代所有图像,请使用Loader.images
。它是包含其属性中图像的所有引用的对象。
像这样使用:
var images = [{name: "img1", src: "http://...a.."},
{name: "img2", src: "http://...b.."},
...
{name: "imgN", src: "http://...N.."}];
function onProgressUpdate(progress){
...
drawProgressBar(progress); // just an example of what you can do
...
}
function onComplete(){
...
// get an Image from Loader object
var texture = Loader.getImage("img2");
// or use this:
var texture = Loader.images.img2; // or still Loader.images["img2"]
...
// iterate over the images
for (var img in Loader.images){
console.log(Loader.images[img].src);
}
....
}
Loader.preload(images, onComplete, onProgressUpdate);
Check the demo如果你没有。