试图在画布中延迟图像以延迟图像
问题描述:
我有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)
}
这似乎是工作像我想它。
答
基于下面的代码片段:
//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
答
//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();
答
而不是使用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);