在 html5/javascript 中预加载图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9334083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
preloading images in html5/javascript
提问by Adam
I've seen example of preloading using multiple images, however I dont know how to apply them to my situation where I only have one image and I'm swapping out frames using the src.
我已经看到使用多个图像进行预加载的示例,但是我不知道如何将它们应用于我只有一张图像并且我正在使用 src 换出帧的情况。
I have a sprite animation that I'm doing, but since there so many images I want to use, I'll have to load them before beginning.
我有一个我正在做的精灵动画,但由于我想要使用的图像太多,我必须在开始之前加载它们。
I know the onload fires every time the src is switched and loaded.
我知道每次切换和加载 src 时都会触发 onload。
How do I preload the images before running the timer? If I'm using "img" onload to preload, do I have to use another Image object to actually display?
如何在运行计时器之前预加载图像?如果我使用“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>
Edit:
编辑:
I ended up with the following code. However, I think I'm going to check out that sprite sheet method mentioned below.
我最终得到了以下代码。但是,我想我要检查一下下面提到的精灵表方法。
I basically trying to do full screen video with short clips because I've been reading video in html5 still has its problems with full screen. Also, I think I can get better quality.
我基本上尝试使用短片制作全屏视频,因为我一直在阅读 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>
回答by Simon Sarris
This is not the way to go about this.
这不是解决这个问题的方法。
If the number was smaller I'd offer a second solution but if you seriously have 668 images you need to cut waaaay down. You don't want every user (and your server) making 668 requests and you certainly don't want one IMG thats constantly swapping out the src either.
如果数字较小,我会提供第二个解决方案,但如果您真的有 668 张图像,则需要减少 waaaay。您不希望每个用户(和您的服务器)发出 668 个请求,而且您当然也不希望一个 IMG 不断地换出 src。
You need to make a sprite sheet. A single image that looks like this.
你需要制作一个精灵表。看起来像这样的单个图像。
Use something like texturepacker to make your single-image sprite sheet: http://www.texturepacker.com/
使用像 texturepacker 这样的东西来制作你的单图像精灵表:http: //www.texturepacker.com/
When it comes time to draw onto the canvas you will need an array that has the x,y,width,height coordinates of each possible sprite in the larger image.
当需要在画布上绘制时,您将需要一个数组,该数组具有较大图像中每个可能精灵的 x、y、宽度、高度坐标。
Instead of doing drawImage(img, x, y)
you will use the canvas method drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
.
drawImage(img, x, y)
您将使用画布方法而不是这样做drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
。
This lets you specify the source rectangle, which will be different for each image. Specifically those arguments correspond to this:
这让您可以指定源矩形,每个图像的源矩形都不同。具体来说,这些参数对应于:
回答by Vasiliy Mazhekin
here is an html5 example how load several images using knockoutjs https://github.com/mazhekin/HTML5MultiLoadImages
这是一个 html5 示例,如何使用 Knockoutjs https://github.com/mazhekin/HTML5MultiLoadImages加载多个图像