Reputation: 9049
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.
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.
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?
<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.
<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>
Upvotes: 1
Views: 11239
Reputation: 688
here is an html5 example how load several images using knockoutjs https://github.com/mazhekin/HTML5MultiLoadImages
Upvotes: 0
Reputation: 63812
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.
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/
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.
Instead of doing drawImage(img, x, y)
you will use the canvas method 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:
Upvotes: 12