2013-04-05 108 views
0

我有25张图像我想很快显示,有点像幻灯片没有效果。我的图像被命名为0到26.试图在画布中延迟图像以延迟图像

我试着设置for循环和setTimeout的延迟,但setTimeout只运行在for循环的结尾,在我的检查点显示i = 25。

JS:

function startAnimation(){ 
for(var i=0; i<25; i++){ 
    setTimeout(function(){ 
     img = new Image(); 
     img.src = 'images/canvas/'+[i]+'.jpg'; 
     img.onload = function(){ctx.drawImage(img,0,0, 850,194)} 

     alert('CP. In setTimeout. i= '+i); 
    },1000); 
    ctx.clearRect(0,0,canvas.width, canvas.height); //clear image after 1 sec, loop to show next. 
    alert('CP outside. i = '+i);    
} 

}

我跟着这个解决方案How do I add a delay in a JavaScript loop?

function startAnimation(){ 
    setTimeout(function(){ 
     img = new Image(); 
     img.src = 'images/canvas/'+[counter]+'.jpg'; 
     img.onload = function(){ctx.drawImage(img,0,0, canvas.width,canvas.height)}; 
     counter++; 
     if(counter<26){ 
      startAnimation(); 
     } 
    },150) 
} 

这似乎是工作像我想它。

回答

3

基于下面的代码片段:

//clear image after 1 sec, loop to show next. 

看来你误解了setTimeout的工作原理。返回前setTimeout函数不会等待。它会立即返回并计划传递给它的代码/函数以在稍后执行(在您的案例中为1秒)。所以你的循环做的是创建25个setTimeouts,它们在循环执行后都会同时执行一秒。

有两种解决方法。一,创建25和一个定时器,每一个第二比其他更高版本:

for(var i=0; i<25; i++){ 
    setTimeout(function(){/* ... */}, 1000 * i); 
} 

或者打电话的setTimeout递归处理您的图像列表:

function foo (i) { 
    /* ... */ 
    if (i >= 0) { 
     setTimeout(foo(i-1),1000); 
    } 
} 

foo(24); 

第二种形式是比较常见的。


除了setTimeout问题。您还需要在阅读了如何关闭内部工作循环,因为在你的循环中的所有一个定时器,将与i = 24值执行的i而不是值1至24

参见:Please explain the use of JavaScript closures in loops

4
//preload your images into an array first for smoother animation 

function getImages(callback) { 

    var imgs = [], 
    loaded = 0, 
    length = 25, 
    i; 

    for (i = 0; i < length; i++) { 
    (function (i) { 
     //create image 
     var img = new Image(); 
     //set a callbacl 
     img.onload = function() { 
     //add to array 
     imgs[i] = img; 
     //increment loaded count 
     loaded++; 
     //if we loaded all of them, call the callback passing in the images 
     if (loaded === length) callback(imgs); 
     } 
     //load 
     img.src = 'images/canvas/' + [i] + '.jpg'; 
    }(i)); 
    } 
} 

function startAnimation(i) { 

    //get all images 
    getImages(function (imgs) { 

    var i = 0; 

    //run through ueach in an interval 
    var animationInterval = setInterval(function() { 

     ctx.clearRect(0, 0, canvas.width, canvas.height); 

     if (i < imgs.length) { 
     ctx.drawImage(img[i++], 0, 0, 850, 194) 
     } else { 
     clearInterval(animationInterval); 
     } 

    }, 1000); 

    }); 
} 

//call 
startAnimation(); 
2

而不是使用setTimeout和for循环,如果你使用的setInterval像这样会更好的......

var i = 0, 
    img; 

function startAnimation() { 
    if (i >= 24) { 
     clearInterval(timer); // or i = 0; 
    } 
    i++; 
    img = new Image(); 
    img.src = 'images/canvas/' + [i] + '.jpg'; 
    img.onload = function() { 
     ctx.drawImage(img, 0, 0, 850, 194); 
    }; 

    alert('CP. In setTimeout. i= ' + i); 

    ctx.clearRect(0, 0, canvas.width, canvas.height); //clear image after 1 sec, loop to show next. 
    alert('CP outside. i = ' + i); 
} 

var timer = setInterval(startAnimation, 1000);