Search code examples
jquerycssloopsanimationdelay

Looped animations firing at once instead of one by one


I have a stack of images with opacity 0. They are the same size and are positioned absolutely on top of each other. I'd like to fade them in one by one so that they appear one by one on top of each other. I'm using jquery/javascript. So far, everything I've tried has caused them to fade in altogether instead of one by one. Any suggestions please?

html:

<div class="img-container">         
    <img src="img/stacked8.jpg" class="stacked" id="stacked8" />
    <img src="img/stacked7.jpg" class="stacked" id="stacked7"  />
    <img src="img/stacked6.jpg" class="stacked" id="stacked6"  />
    <img src="img/stacked5.jpg" class="stacked" id="stacked5"  />
    <img src="img/stacked4.jpg" class="stacked" id="stacked4"  />
    <img src="img/stacked3.jpg" class="stacked" id="stacked3"  />
    <img src="img/stacked2.jpg" class="stacked" id="stacked2"  />
    <img src="img/stacked1.jpg" class="stacked" id="stacked1" />
    <img src="img/stacked0.jpg" />      
</div>

css:

.img-container {
    width: 100%;
    height: auto;
    position: relative;
}

.img-container .stacked {
    position: absolute;
    left: 0;
    top: 0;
    opacity: 0;
}

jquery with waypoint:

var waypoint = new Waypoint({
      element: document.getElementById('start-stack'),
      handler: function(direction) {
        if (direction == 'down') {
            doLoop();
        }
        if (direction == 'up') {
            
            
        }
      }, offset: '75%'
      
    });
        
    function doLoop() {
        for (var i=0; i<8; i++) {
            (function(i) {
                setTimeout(function() { $('#stacked' + i).animate({'opacity': '1'}, 1000); }, 100 * i);
             })(i);
        }
    }

Solution

  • May I offer you use CSS transitions instead of animating opacity otherwise. Use a class with opacity:1 and toggle it according to the picture you want visible.

    function doLoop() {
      for (var i = 1; i <= 8; i++) {
        (function(i) {
          setTimeout(function() {
            $('.stacked').removeClass("active");
            $('#stacked' + i).addClass("active");
          }, 250 * i);
        })(i);
      }
    }
    
    doLoop()
    .img-container {
      width: 100%;
      height: auto;
      position: relative;
    }
    
    .img-container .stacked {
      position: absolute;
      left: 0;
      top: 0;
      opacity: 0;
      transition: 250ms all;
    }
    
    .img-container .stacked.active {
      opacity: 1;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="img-container">
      <img src="https://picsum.photos/id/237/320/200" class="stacked" id="stacked8" />
      <img src="https://picsum.photos/id/236/320/200" class="stacked" id="stacked7" />
      <img src="https://picsum.photos/id/235/320/200" class="stacked" id="stacked6" />
      <img src="https://picsum.photos/id/234/320/200" class="stacked" id="stacked5" />
      <img src="https://picsum.photos/id/233/320/200" class="stacked" id="stacked4" />
      <img src="https://picsum.photos/id/232/320/200" class="stacked" id="stacked3" />
      <img src="https://picsum.photos/id/231/320/200" class="stacked" id="stacked2" />
      <img src="https://picsum.photos/id/230/320/200" class="stacked" id="stacked1" />
      <img src="https://picsum.photos/id/229/320/200" />
    </div>