Javascript - 在不同间隔的图像之间切换

时间:2014-09-22 08:06:01

标签: javascript image animation

我想在初始延迟后以两个不同的间隔在两个png图像之间自动切换:

  1. 图像A显示2秒(初始延迟)
  2. 图像B显示为0.3秒
  3. 图像A显示6秒
  4. 从第2步重复
  5. 我发现问题Javascript - Switching Between Two Images带有letiagoalves’教学代码,显示了如何在两个图像之间切换,显示相同时间内的两个图像:

    <img id="Change_Image" src="http://placehold.it/200x200" alt="Letter A">
    
    function change_image() {
        var url = document.getElementById('Change_Image').src;
        if (url == 'http://placehold.it/200x200') {
            document.getElementById('Change_Image').src = 'http://placehold.it/100x100';
        } else {
            document.getElementById('Change_Image').src = 'http://placehold.it/200x200';
        }
    }
    
    setInterval(change_image, 2000);
    

    (Working demo at jsfiddle)

    ...并尝试修改它以使用setInterval()setTimeout的各种组合显示不同时间的图像,到目前为止无济于事:< / p>

    1. 使用一个setTimeout()和两个setInterval()
      • 这里的想法是图片A显示为开始,start_animation()使用setTimeout()等待2秒,然后调用change_image()显示图片B.同时,每0.3秒调用change_back(),因此图像B从不显示超过0.3秒,并且每6秒调用change_image(),因此图像B每6秒显示一次。
      • 结果 - 图像会切换,但间隔有点不确定:有时图像B会在预期时间内显示,有时会非常短暂地闪烁。我想这是因为change_image()change_back()同时执行时的干扰模式。
    2. 代码:

      function start_animation() {
              change_image();
      }
      
      function change_image() {
          document.getElementById('Change_Image').src = 'http://placehold.it/100x100';
      }
      
      function change_back() {
          document.getElementById('Change_Image').src ='http://placehold.it/200x200';   
      }
      
      var initialTimout = 2000; //Time in milliseconds
      var longInterval = 6000; //Time in milliseconds
      var shortInterval = 300; //Time in milliseconds
      
      setTimeout(start_animation, initialTimout);
      setInterval(change_image, longInterval);
      setInterval(change_back, shortInterval);
      

      (Working demo at jsfiddle)

      1. 使用一个setInterval()并随着时间的推移更改时间间隔:
        • 这里的想法change_image()处理所有图像更改,并根据显示的图像,setInterval的间隔发生变化。
        • 结果 - 此解决方案同时显示两个图像(初始超时时间),这不是目标。我研究了如何在函数外部更改变量,但必须弄错,或者JS在调用setInterval()后不允许更改间隔。
      2. 代码:

        interval = 2000;
        
        function change_image() {
            var url = document.getElementById('Change_Image').src;
            if (url == 'http://placehold.it/200x200') {
                document.getElementById('Change_Image').src = 'http://placehold.it/100x100';
                window.interval = 300;
            } else {
                document.getElementById('Change_Image').src = 'http://placehold.it/200x200';
                window.interval = 6000;
            }
        }
        
        setInterval(change_image, interval);
        

        (Working demo at jsfiddle)

        1. 使用连续的setTimeout()
          • 这里的想法是让change_image()change_back()在最初的2秒超时后反复调用对方并使用setTimeout()来确保呼叫被延迟,它们之间的时间是正确的。
          • 结果 - 似乎根本不起作用:仅显示图片A.
        2. 代码:

          function start_animation() {
              change_image();
          }
          
          function change_image() {
              document.getElementById('Change_Image').src = 'http://placehold.it/100x100';
              change_back();
          }
          
          function change_back() {
              document.getElementById('Change_Image').src ='http://placehold.it/200x200';   
          }
          
          
          setTimeout(start_animation, 2000);
          setTimeout(change_back(), 300);
          setTimeout(change_image(),6000);
          

          (Working demo at jsfiddle)

          在Javascript中有解决此问题的好方法吗?

          如何吗

3 个答案:

答案 0 :(得分:1)

使用连续的setTimeouts是可行的方法(#3)。

当您尝试在300毫秒到6000毫秒之间切换时,多个间隔(或根本间隔)会变得混乱。您正在考虑清除间隔或尝试以某种方式“同步”图像交换(但如果您让它运行得足够长,您将看到图像A与图像交换过快B等等。

这是一个演示连续超时的小提琴:

http://jsfiddle.net/cCvtL/43/

对于您的示例代码,您不想一次性设置所有计时器,而是希望在计时器运行后连续设置它们。对于2000的初始超时值,我们检查undefined值(来自初始循环调用)。之后,我们会从300传递参数6000setTimeouts

function looper(url, interval){
    // If interval is undefined, we set the value to 2000 (initial)
    // Otherwise, we use the value passed in
    interval = interval === undefined ? 2000 : interval;

    // If url is present, we switch the image source
    if (url) {
        document.getElementById('Change_Image').src = url;
    } else {
        // Default, to keep things tidy.
        url = "http://placehold.it/200x200";
    }

    // Timer logic to handle the next iteration
    setTimeout(function() {
        if (url === "http://placehold.it/200x200") {
            looper("http://placehold.it/100x100", 300);
        } else {
            looper("http://placehold.it/200x200", 6000);
        }
    }, interval);
}

// Kick off the timer!
looper();

答案 1 :(得分:0)

从我的头顶,Promise可以在这里提供帮助;在你的情况下,这种一般的(完全未经测试的,伪编码的)想法会有意义吗? (在这里,使用bluebird

之类的东西
// Show an image, and returns a promise resolved after a number of ms 
var showImage = function (src, howLong) {

   return new Promise(function (resolve, reject) {

     document.getElementById('Change_Image').src = src
     setTimeout(resolve, howLong)

   });

}


// The loop part
var recur = function loop() {
  return showImage("url-of-imageB",300).then(function () {
       return showImage("url-of-imageA",6000)
  }).then(recur);
}

// Show A, then loop
showImage("url-of-imageA",2000).then(recur);

答案 2 :(得分:0)

这是一个简单的技巧,你几乎得到它你只需要超时

function change_image() {
    var url = document.getElementById('Change_Image').src;
    console.log(url);
    if (url == 'wdw.tv.png') {
        setTimeout(function(){
                document.getElementById('Change_Image').src = 'slmn.png';
            }, 2000);
    } else {
        setTimeout(function(){
                document.getElementById('Change_Image').src = 'wdw.tv.png';
            }, 2000);
    }
}

setInterval(change_image, 4000);

初始延迟为4秒,它会在2秒后显示图像A,然后从该点开始,它将每2秒在两个之间切换。

只是玩这个间隔。虽然如果你有更多的图像,它将是不同的。 希望这有助于你开始。

这是 fiddle demo

<强> **** **** EDIT

根据下面的评论,这可以消除不稳定的行为

function change_image(url) {
    if(url){
        document.getElementById('Change_Image').src= url;
    }
    if (url == 'img1.png') {
        window.setTimeout(change_image, 300, 'img2.gif');
    } else {
        window.setTimeout(change_image, 6000, 'img1.png');
    }
}

setTimeout(change_image(), 2000);

<强> Demo Here