Search code examples
jquerycssanimationcss-transitionsdelay

Delay Animations While Scrolling


I'm trying to create animations as the user scrolls but I also want to stagger them in that they don't all happen at the same time but one after the other in quick succession.

I'm using the following which adds a class to the div which triggers css animations then I'm trying to use a setTimeout to delay the next animation by just a bit. I would think since it's in an $.each() loop it would hit each timeout but instead they all fade in at the time time...
JSFiddle

EDIT I believe I need to do this in JS as I have many animations on a page with a mixture of animations types and need to delay the adding of the class by a few milliseconds.

/**
 * Check if Animation is currently in view
 */
function anim_in_view() {
  var window_height = $(window).height();
  var window_top_position = $(window).scrollTop();
  var window_bottom_position = (window_top_position + window_height);
  var $animations = $('body .animate');

  if ($animations.length) {
    $.each($animations, function() {
      var $elm = $(this);
      var element_height = $elm.outerHeight();
      var element_top_position = $elm.offset().top + 50;
      var element_bottom_position = (element_top_position + element_height);

      setTimeout(function() {
        if ((element_bottom_position >= window_top_position) &&
          (element_top_position <= window_bottom_position)) {
          // $elm.delay( 2000 ).addClass( 'visible' );
          $elm.addClass('visible');
        }
      }, 1000);
    });
  }
}
$(window).on('load scroll resize', anim_in_view);
.flex {
  margin-top: 1000px;
  margin-bottom: 500px;
  display: -webkit-flex;
  display: flex;
}
.flex > div {
  width: 33.33%;
  height: 200px;
}
.red {
  background: #f00;
}
.green {
  background: #0f0;
}
.blue {
  background: #00f;
}
.animate-opacity {
  opacity: 0;
  -webkit-transition: opacity 1s ease-in-out;
  transition: opacity 2s ease-in-out;
}
.animate-opacity.visible {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fadeIns" class="flex">
  <div class="animate animate-opacity red"></div>
  <div class="animate animate-opacity green"></div>
  <div class="animate animate-opacity blue"></div>
</div>


Solution

  • You could use transition-delay to achieve this:

    .animate-opacity:nth-child(2) {
      transition-delay: 1s;
    }
    .animate-opacity:nth-child(3) {
      transition-delay: 2s;
    }
    

    /**
     * Check if Animation is currently in view
     */
    function anim_in_view() {
      var window_height = $(window).height();
      var window_top_position = $(window).scrollTop();
      var window_bottom_position = (window_top_position + window_height);
      var $animations = $('body .animate');
    
      if ($animations.length) {
        $.each($animations, function() {
          var $elm = $(this);
          var element_height = $elm.outerHeight();
          var element_top_position = $elm.offset().top + 50;
          var element_bottom_position = (element_top_position + element_height);
    
          if ((element_bottom_position >= window_top_position) &&
            (element_top_position <= window_bottom_position)) {
            // $elm.delay( 2000 ).addClass( 'visible' );
            $elm.addClass('visible');
          }
        });
      }
    }
    $(window).on('load scroll resize', anim_in_view);
    .flex {
      margin-top: 1000px;
      margin-bottom: 500px;
      display: -webkit-flex;
      display: flex;
    }
    .flex > div {
      width: 33.33%;
      height: 200px;
    }
    .red {
      background: #f00;
    }
    .green {
      background: #0f0;
    }
    .blue {
      background: #00f;
    }
    .animate-opacity {
      opacity: 0;
      -webkit-transition: opacity 1s ease-in-out;
      transition: opacity 2s ease-in-out;
    }
    .animate-opacity:nth-child(2) {
      transition-delay: 1s;
    }
    .animate-opacity:nth-child(3) {
      transition-delay: 2s;
    }
    .animate-opacity.visible {
      opacity: 1;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="fadeIns" class="flex">
      <div class="animate animate-opacity red"></div>
      <div class="animate animate-opacity green"></div>
      <div class="animate animate-opacity blue"></div>
    </div>