1

我正在使用 JcanvaScript 库来处理 Html5 画布,现在我想在我的画布中加载一些图像,但只有最后一个图像加载成功,除了最后一个,我看不到任何其他图像,我不知道是什么我的代码错了。

这是代码

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      canvas {
           border: 1px solid #9C9898;
       }
    </style>
      <script src="jcanvas/jCanvaScript.1.5.15.js"></script>
      <script>
          var imagesUrl = [];
          var imagesObj = [];
          var canvasWidth = 800;
          var canvasHeight = 600;
          var imagesIdPrefix = 'images_';
          var canvas = "canvas";
          var fps = 60;

          imagesUrl.push('images/image1.jpg');
          imagesUrl.push('images/image2.jpg');
          imagesUrl.push('images/image3.jpg');
          imagesUrl.push('images/image4.jpg');

          function init(){
              for (i = 0; i < imagesUrl.length; i++){
                  var xImage = new Image();
                  xImage.src = imagesUrl[i];
                  xImage.onload = function(){
                      jc.start(canvas, fps);
                      jc.image(xImage, i*10, 0, 200, 200)
                              .id(imagesIdPrefix.toString() + i.toString());
                      jc.start(canvas, fps);
                  }
                  imagesObj.push(xImage);
              }
          }

      </script>
  </head>
  <body onload="init()">
    <canvas id="canvas" width="800px" height="600px"></canvas>
  </body>
</html>
4

2 回答 2

2

该错误已由 MrOBrian 在评论中确定:当调用 onload 回调时, i 具有它在循环结束时的值。这就是为什么您认为只有最后一个图像加载成功的原因。

一个标准的解决方案是将循环的内容嵌入到一个闭包中,保持 i 的值:

for (i = 0; i < imagesUrl.length; i++){
     (function(i){
              var xImage = new Image();
              xImage.src = imagesUrl[i];
              xImage.onload = function(){
                  jc.start(canvas, fps);
                  jc.image(xImage, i*10, 0, 200, 200)
                          .id(imagesIdPrefix.toString() + i.toString());
                  jc.start(canvas, fps);
              }
              imagesObj.push(xImage);
       })(i);
   }

编辑 :

当您想确保在运行某些代码之前加载所有需要的图像时,您可以使用此功能:

function onLoadAll(images, callback) {
    var n=0;
    for (var i=images.length; i-->0;) {
        if (images[i].width==0) {
            n++;
            images[i].onload=function(){
                if (--n==0) callback();
            };
        }
    }
    if (n==0) callback();
}

图像必须首先提供它们的 src。你这样调用函数:

onLoadAll(imagesObj, function(){
     // do something with imagesObj
});
于 2012-08-21T16:22:44.813 回答
1

您需要确保图像已加载,然后再循环浏览它们。

通过在循环内定义您的onload函数for,图像可能尚未加载,因此脚本将跳过它。当它完成循环时,最后一张图像可能是唯一及时加载的图像。

我建议为循环的每个图像添加一个加载器for,当所有图像都加载完毕后,继续循环遍历数组。

加载器和检查器看起来像这样:

var loadedImages = [];
var loadedNumber = 3 //the number of images you need loaded    
var imageToBeLoaded = new Image();
imageToBeLoaded.onload = function() {
    loadedImages.push(true);
    checkImages();
}
function checkImages() {
    if (loadedImages.length != loadedNumber) {
        setTimeout(checkImages(),1000);
    } else {
        init(); //your draw function
    }
}
于 2012-08-21T14:39:40.233 回答