最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I handle many images in my HTML5 canvas? - Stack Overflow

programmeradmin1浏览0评论

I'm very new to Html5 canvas and Javascript. I'm trying this :

function animate() {    
   var image1 = new Image();
   image.src = /path
   var image2 = new Image();
   image2.src = /path
   for(;;)
   {
        //change value of x and y so that it looks like moving
        context.beginPath();
        context.drawImage(<image>, x, y );
        context.closePath();
        context.fill();
   }
}

EDIT:

And I call the animate function each 33ms :

if (playAnimation) {
            // Run the animation loop again in 33 milliseconds
            setTimeout(animate, 33);
        };

If I follow the answer given here, I get the image struck and its not moving any further.

I'm very new to Html5 canvas and Javascript. I'm trying this :

function animate() {    
   var image1 = new Image();
   image.src = /path
   var image2 = new Image();
   image2.src = /path
   for(;;)
   {
        //change value of x and y so that it looks like moving
        context.beginPath();
        context.drawImage(<image>, x, y );
        context.closePath();
        context.fill();
   }
}

EDIT:

And I call the animate function each 33ms :

if (playAnimation) {
            // Run the animation loop again in 33 milliseconds
            setTimeout(animate, 33);
        };

If I follow the answer given here, I get the image struck and its not moving any further.

Share Improve this question edited Jul 21, 2012 at 2:19 batman asked Jul 20, 2012 at 12:50 batmanbatman 4,9289 gold badges41 silver badges49 bronze badges 4
  • Do you want to draw them all to the same location (in succession) or do you want to draw them all to different locations? More details are needed to really help you. – Phrogz Commented Jul 20, 2012 at 12:53
  • OK, edited my answer with details for that, then. – Phrogz Commented Jul 20, 2012 at 12:58
  • And where do you want the images to move? Randomly? In a line? In separate predetermined paths? – Phrogz Commented Jul 21, 2012 at 14:47
  • @Phrogz: I will calculating the value for x and y in my for loop. It will be moving in a circular path .. – batman Commented Jul 22, 2012 at 16:56
Add a ment  | 

1 Answer 1

Reset to default 9

Update: Based on new information in the question, your problem (restated) is that you want to either

  1. wait for all images to load first, and then start animating with them, or
  2. start animating and only use an image if it is available.

Both are described below.

1. Loading many images and proceeding only when they are finished

With this technique we load all images immediately and when the last has loaded we run a custom callback.

Demo: http://jsfiddle/3MPrT/1/

// Load images and run the whenLoaded callback when all have loaded;
// The callback is passed an array of loaded Image objects.
function loadImages(paths,whenLoaded){
  var imgs=[];
  paths.forEach(function(path){
    var img = new Image;
    img.onload = function(){
      imgs.push(img);
      if (imgs.length==paths.length) whenLoaded(imgs);
    }
    img.src = path;
  });
}

var imagePaths = [...]; // array of strings
loadImages(imagePaths,function(loadedImages){
  setInterval(function(){ animateInCircle(loadedImages) }, 30);
});

2. Keeping track of all images loaded so far

With this technique we start animating immediately, but only draw images once they are loaded. Our circle dynamically changes dimension based on how many images are loaded so far.

Demo: http://jsfiddle/3MPrT/2/

var imagePaths = [...]; // array of strings
var loadedImages = [];  // array of Image objects loaded so far

imagePaths.forEach(function(path){
  // When an image has loaded, add it to the array of loaded images
  var img = new Image;
  img.onload = function(){ loadedImages.push(img); }
  img.src = path;
});

setInterval(function(){
  // Only animate the images loaded so far
  animateInCircle(loadedImages);
}, 100);

And, if you wanted the images to rotate in a circle instead of just move in a circle:

Rotating images: http://jsfiddle/3MPrT/7/

ctx.save();
ctx.translate(cx,cy); // Center of circle
ctx.rotate( (angleOffset+(new Date)/3000) % Math.TAU );
ctx.translate(radius-img.width/2,-img.height/2);
ctx.drawImage(img,0,0);
ctx.restore();

Original answer follows.

In general, you must wait for each image loading to plete:

function animate(){
  var img1 = new Image;
  img1.onload = function(){
    context.drawImage(img1,x1,y1);
  };
  img1.src = "/path";

  var img2 = new Image;
  img2.onload = function(){
    context.drawImage(img2,x2,y2);
  };
  img2.src = "/path";
}

You may want to make this code more DRY by using an object:

var imgLocs = {
  "/path1" : { x:17, y:42  },
  "/path2" : { x:99, y:131 },
  // as many as you want
};

function animate(){
  for (var path in imgLocs){
    (function(imgPath){
      var xy = imgLocs[imgPath];
      var img = new Image;
      img.onload = function(){
        context.drawImage( img, xy.x, xy.y );
      }
      img.src = imgPath;
    })(path);
  }
}
发布评论

评论列表(0)

  1. 暂无评论