2012-02-17 66 views
1

我见过预加载使用多个图像的例子,但是我不知道如何将它们应用到我只有一个图像的情况,我用src换出了帧。预加载图像在html5/javascript

我有一个精灵动画,我正在做,但由于有很多图像我想要使用,我必须在开始之前加载它们。

我知道onload会在每次src切换和加载时触发。

如何在运行定时器之前预加载图像?如果我使用“img”onload预加载,是否必须使用另一个Image对象来实际显示?

<script type="text/javascript"> 
function init(){ 
    var numLabel; 
    var imgNumber = 1; 
    var lastImgNumber = 668; 
    var canvas = document.getElementById("mycanvas"); 
    var context = canvas.getContext("2d"); 
    var img = new Image; 

    img.onload = function(){ 
     context.clearRect(0,0,context.canvas.width,context.canvas.height); 
     context.drawImage(img,0,0); 
    }; 
    var timer = setInterval(function(){ 
     if(imgNumber>lastImgNumber){ 
     clearInterval(timer); 
     }else{ 
     numLabel = padNum(imgNumber++,5); 
     img.src = "sprite images/opt/movie"+numLabel+".jpg"; 
     } 
    }, 1000/24); 
} 
function padNum(num, digits){ 
    var str = num + ""; 
    return num.length >= digits? str: padNum("0" + str, digits); 
} 
</script> 

编辑:

我结束了下面的代码。不过,我想我会看看下面提到的sprite sheet方法。

我基本上试图用短剪辑来做全屏视频,因为我一直在阅读html5视频,但仍然有全屏的问题。另外,我认为我可以获得更好的质量。

<script type="text/javascript"> 
     var imageArray = new Array(); 
     var loadedImages = new Array(); 

     function init(){ 

      buildImageArray(); //Execute the function to create the array of images 
      var total = imageArray.length; 
      var count = 0; 



      // loop through the images and load. 
      while(count < total) { 
       loadImage("sprite images/opt/" + imageArray[count],count); 


       count++; 
      } 


     } 


     function padNum(num, digits){ 
      var str = num + ""; 
      return num.length >= digits? str: padNum("0" + str, digits); 
     } 

     function buildImageArray(){ 
      var firstImage = 1; 
      var lastImgNumber = 668; 
      var numLabel; 


      for(var i = firstImage; i<lastImgNumber+1;i++){ 
       numLabel = padNum(i,5); 
       imageArray.push("movie"+numLabel+".jpg"); 
      } 
     } 


     function loadImage(imageSrc,position) { 
     // actual function that loads image into DOM 

     var image = new Image(); // local scope, new object created per instance. 
     image.onload = function() { 
      if (!image) return; 

      loadedImages[position] = image.src; // record this image path as loaded in global scope 
      // or... store the objects themselves so you can inject them: 
      // loadedImages.push(this); 

      // sample report of progress 
      reportProgress(); 

      // remove event and self to prevent IE on animated gif loops and clear up garbage. 
      image = image.onload = image.onabort = image.onerror = null; 
     }; 

     image.src = imageSrc; 
     } 


     function reportProgress() { 
     // used to show how many images loaded thus far and/or trigger some event you can use when done. 

     // optional to show onscreen..., 'where' should be an object referencing an element in the DOM 
     // to do it silently, just remove the output bits below. 
     var output = "loaded "; 
     output += loadedImages.length; 
     output += " of "; 
     output += imageArray.length; 
     output += " images."; 
     $("#loader").html(output); 

      // this bit will fire when all images done: 
      if (imageArray.length == loadedImages.length) { 
       // total images onComplete. done. rewrite as you deem fit - call your main site load function from here 

       // keep in mind that if 1 of your images is a 404, this function may not fire, you 
       // may want to assign onerror and onabort events 

       //fire beginAnimation 
       beginAnimation(); 
      } 
     } 


     function beginAnimation(){ 
      var canvas = document.getElementById("mycanvas"); 
      var context = canvas.getContext("2d"); 
      var img = new Image; 
      var imgNumber = 0; 
      var lastImgNumber = 667; 


      img.onload = function(){ 
       context.clearRect(0,0,context.canvas.width,context.canvas.height); 
       context.drawImage(img,0,0); 


      }; 
      var timer = setInterval(function(){ 
       if(imgNumber>lastImgNumber){ 

        clearInterval(timer); 

       }else{ 

        img.src = loadedImages[imgNumber]; 
       } 
       imgNumber++; 


      }, 1000/20); 

     } 

    </script> 
+1

加载多个图像和你的问题是什么? – 2012-02-17 19:23:37

回答

11

这是不走这个路。

如果数量较小,我会提供第二种解决方案,但如果您认真拥有668张图片,则需要将其剪掉。你不希望每个用户(和你的服务器)发出668个请求,你当然不希望有一个IMG不断地换出src。

您需要制作精灵表。单个图像看起来像this

使用类似texturepacker让你的单幅影像精灵表:http://www.texturepacker.com/

当谈到时间绘制在画布上,您将需要一个具有X,Y,宽度的阵列,身高每一个可能的坐标精灵在较大的图像。

而不是做drawImage(img, x, y)您将使用画布方法drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

这使您可以指定源矩形,每个图像的矩形将不同。具体这些参数对应于此:

enter image description here

+0

正如我编辑中提到的那样,我想将短片添加到我的网站设计中。假设我使用1920x1080图像。这将意味着一个巨大的精灵表。当然,我会预加载精灵表,但可以“它”处理大图像? – Adam 2012-02-18 00:52:12

+0

如果您上传了实际的视频文件并将其绘制到画布上,那会更好。你实际上可以使用'drawImage'和'

+0

另外,我现在只使用668,但我认为我只需要200 – Adam 2012-02-18 01:01:40