【问题标题】:Trying to loop through images with a delay in canvas尝试在画布中有延迟的图像循环
【发布时间】:2013-04-05 01:31:55
【问题描述】:

我有 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)
}

它似乎按我想要的方式工作。

【问题讨论】:

    标签: javascript html arrays loops delay


    【解决方案1】:
    //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】:

      基于以下sn-p的代码:

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

      您似乎误解了setTimeout 的工作原理。 setTimeout 函数在返回之前不会等待。它立即返回并安排传递给它的代码/函数在以后执行(在您的情况下为 1 秒)。因此,您的循环所做的是创建 25 个 setTimeouts,它们都在循环执行后一秒同时执行。

      有两种解决方案。一,每晚一秒创建 25 个 setTimeouts:

      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 问题。您还需要了解闭包在循环内的工作方式,因为在您的循环中,所有 setTimeouts 都将以 i = 24 的值执行,而不是 i 的值是 1 到 24。

      见:Please explain the use of JavaScript closures in loops

      【讨论】:

        【解决方案3】:

        与其使用 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);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-05
          • 1970-01-01
          • 2018-10-31
          相关资源
          最近更新 更多