【问题标题】:Javascript load images in canvas with JCanvaScriptJavascript 使用 JCanvaScript 在画布中加载图像
【发布时间】:2012-08-16 21:58:58
【问题描述】:

我正在使用 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>

【问题讨论】:

  • 您在回调函数中使用了迭代器变量,因此onload 函数中i 的值将始终相同。此外,您的 i 变量是全局的;你应该在它前面加上var

标签: javascript arrays canvas html5-canvas


【解决方案1】:

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

【讨论】:

  • 您的代码消除了另一个问题,所有图像加载正常但无序。你知道怎么回事吗?
  • 加载顺序不一定是初始化的顺序,因为它取决于网络。如果你愿意,我可以建议你一个函数,它只在所有图像都加载时调用你的代码。
  • 哇它好用,我在 onLoadAll 回调中添加了所有画布卓尔函数,一切正常。非常感谢!!!!!! :)
  • 不客气。知道一个有用的东西总是很高兴:)
【解决方案2】:

您需要确保在遍历图像之前加载图像。

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

我建议在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
    }
}

【讨论】:

    猜你喜欢
    • 2013-01-23
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多