Skip to content
Fix Code Error

Animating Elements in One by One

July 17, 2021 by Code Error
Posted By: Anonymous

I am trying to make an on scroll jQuery sequence that animates elements in one after the other when it’s in view. Here is my CodePen and here is the code:

$(document).ready( function() {
    
  var $window = $(window);
  var $animatedItem = $('.has-animation');
  $animatedItem.css({ 
    "visibility": "hidden"
  });

  // Check if in view.
  function runAnimation() {
    var windowTop = $window.scrollTop();
    var windowHeight = $window.height();
    var windowWidth = $window.width();
    var windowBottom = (windowTop + windowHeight + windowWidth);

    $animatedItem.each( function() {
      var $element = $(this);
      var elementTop = $element.offset().top;
      var elementHeight = $element.outerHeight();
      var elementWidth = $element.outerWidth();
      var elementBottom = (elementTop + elementHeight + elementWidth);
      
      if (windowTop > elementTop - windowHeight / 1.2) {      
        // Check to see if this current container is within viewport.
        if ((elementBottom >= windowTop) && (elementTop <= windowBottom)) {
          
          $element.each( function(i) {
            // Stagger the elements into view.     
            setTimeout( function() {
              $element.eq(i).removeClass('has-animation').css({
                "visibility": "visible"
              });
              $element.eq(i).addClass('animated');
              $element.eq(i).addClass('in-view');
            }, 330 * (i+1));
            
          });

        }
      }
    });
  }
$window.on('scroll resize', runAnimation);
$window.trigger('scroll');

});

I have it so the class ".has-animation" is replaced with ".animated" and ".in-view" when the element is scrolled into view. The element style "visibility" is also changed from hidden to visible.

Currently, when the elements reach the viewpoint, they all simultaneously animate in instead of each element animating in one after another.

I have tried replacing $element in this code:

$element.each( function(i) {
  // Stagger the elements into view.     
  setTimeout( function() {
    $element.eq(i).removeClass('has-animation').css({
      "visibility": "visible"
    });
      $element.eq(i).addClass('animated');
      $element.eq(i).addClass('in-view');
    }, 330 * (i+1));
        
});

With $animatedItem so it looks like this:

$animatedItem.each( function(i) {
  // Stagger the elements into view.     
  setTimeout( function() {
    $animatedItem.eq(i).removeClass('has-animation').css({
      "visibility": "visible"
    });
      $animatedItem.eq(i).addClass('animated');
      $animatedItem.eq(i).addClass('in-view');
    }, 330 * (i+1));
        
});

And this code (the $animatedItem one) actually does what I’m looking for, however, the elements animate immediately upon scroll rather than loading when they get to the viewpoint. This leads me to believe that a function like this should be directed to $animatedItem but near the start of my code?

I’m new (self learning) to JS/JQuery, and I’m having a bit of trouble figuring this out, any help is appreciated! Thanks all!

Solution

The key is about timing.

As soon as some elements get in-view, remove the has-animation class… THEN, set the timeout for the CSS animation to trigger.

Also, you have to refresh the $animatedItem collection… 😉

The result of this answer is best viewed in CodePen

_x000D_

_x000D_

$(document).ready(function () {
  var $window = $(window);
  var $animatedItem = $(".has-animation");
  $animatedItem.css({
    visibility: "hidden"
  });

  // Check if in view.
  function runAnimation() {
    var windowTop = $window.scrollTop();
    var windowHeight = $window.height();
    var windowWidth = $window.width();
    var windowBottom = windowTop + windowHeight + windowWidth;

    $animatedItem.each(function (animated_index) {
      var $element = $(this);
      var elementTop = $element.offset().top;
      var elementHeight = $element.outerHeight();
      var elementWidth = $element.outerWidth();
      var elementBottom = elementTop + elementHeight + elementWidth;

      // Refresh the collection
      $animatedItem = $(".has-animation");

      if (windowTop > elementTop - windowHeight / 1.2) {
        // Check to see if this current container is within viewport.
        if (elementBottom >= windowTop && elementTop <= windowBottom) {
          $element.each(function (i, el) {
            // Stagger the elements into view.
            if ($(el).hasClass("has-animation")) {
              $(el).eq(i).removeClass("has-animation");

              setTimeout(function () {
                console.log(animated_index);
                $(el).css({
                  visibility: "visible"
                });
                $(el).addClass("animated in-view");
              }, 330 * (animated_index + 1));
            }
          });
        }
      }
    });
  }
  $window.on("scroll resize", runAnimation);
  $window.trigger("scroll");
});

_x000D_

/*-----------------------------------------*/
/* Content
/*-----------------------------------------*/

body {
  background-color: #EBE7DE;
}

.content-block {
  margin: 0 auto!important;
  width: 100%;
  clear: both;
}

.common-block {
  display: block;
  position: relative;
  width: 100%;
  margin: 0 auto!important;
}

.content-title {
  font-style: italic;
  color: #19130E;
  margin-top: 40px;
  margin-left: 40px;
}

.content-spacer {
  height: 1400px;
}

body .relative { 
  position: relative; 
}

body .width-1of1 { 
  width: 100%; }

body .white-bg { 
  background-color: #FFF;
}


/*-----------------------------------------*/
/* Column Group
/*-----------------------------------------*/

.column-group {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  margin-bottom: 0px;
  padding: 0;
}

.column {
  display: flex;
  position: relative;
  list-style: none;
  vertical-align: top;
  margin: 0px;
  margin-bottom: 40px;
  padding-right: 20px;
  padding-left: 20px;
  background-clip: content-box;
}

.padding-bottom-1of1 {
  height: 0!important;
  padding-bottom: 100%!important;
}

.overflow-hidden {
  overflow: hidden!important;
}

body .absolute-fill {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

body .prepped-background {
  background-size: cover!important;
  background-repeat: no-repeat!important;
  background-position: center center!important;
}

body .opacity-0 {
  opacity: 0;
}


/*-----------------------------------------*/
/* Devices
/*-----------------------------------------*/

/* DESKTOP */
@media (min-width: 1021px) {
  
  .column-group {
    padding: 0rem 10rem; }
    
    html .column-group.desktop-width-1of3 > .column.responsive { 
    width: 33.3%; 
    box-sizing: border-box; }
  
  html body .desktop-max-width-450 {
    max-width: 450px; }
  
}


/* TABLET */
@media (min-width: 768px) and (max-width: 1020px) {
  
  .column-group {
    padding: 0rem 5rem; }

    html .column-group.tablet-width-1of2 > .column.responsive { 
    width: 50%; 
    box-sizing: border-box; }
  
  html body .tablet-max-width-450 {
    max-width: 450px; }
  
}


/* MOBILE */
@media (max-width: 767px) {  
  
  .column-group {
    padding: 0rem 4rem; }
  
  html .column-group.mobile-width-1of1 > .column.responsive { 
    width: 100%; 
    box-sizing: border-box; }
  
  html body .mobile-max-width-250 {
    max-width: 250px; }
  
  body .mobile-margin-x-auto {
    margin: 0 auto!important;  }
  
}

/*-----------------------------------------*/
/* Animations
/*-----------------------------------------*/

.has-animation {  
    -webkit-animation-play-state: paused;   
    -moz-animation-play-state: paused;
    -ms-animation-play-state: paused;
    -o-animation-play-state: paused;
    animation-play-state: paused;
}

.animated[class*="in-view"] {
    -webkit-animation-fill-mode: both;
    -moz-animation-fill-mode: both;
    -ms-animation-fill-mode: both;
    -o-animation-fill-mode: both;
    animation-fill-mode: both;
    
    
}

.animated {
    -webkit-animation-fill-mode: both;
    -moz-animation-fill-mode: both;
    -ms-animation-fill-mode: both;
    -o-animation-fill-mode: both;
    animation-fill-mode: both;
    
    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    -ms-animation-duration: 1s;
    -o-animation-duration: 1s;
    animation-duration: 1s;

    -webkit-animation-play-state: running;
    -moz-animation-play-state: running;
    -ms-animation-play-state: running;
    -o-animation-play-state: running;
    animation-play-state: running;
}

.animated[class*="in-view"].fade-in-up {
    animation-name: fade-in-up;
    -webkit-animation-name: fade-in-up;
    -moz-animation-name: fade-in-up;
    -o-animation-name: fade-in-up;

    -webkit-animation-delay: .5s;
    -moz-animation-delay: .5s;
    -ms-animation-delay: .5s;
    -o-animation-delay: .5s;
    animation-delay: .5s;

    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    -ms-animation-duration: 1s;
    -o-animation-duration: 1s;
    animation-duration: 1s;
}

@keyframes fade-in-up {
    0% { 
      opacity: 0; 
      transform: translateY(20px); } 
    100% { 
      opacity: 1; 
      transform: translateY(0); }
}

@-webkit-keyframes fade-in-up {
    0% { 
      opacity: 0; 
      -webkit-transform: translateY(20px); }
    100% { 
      opacity: 1; 
      -webkit-transform: translateY(0); }
}

@-moz-keyframes fade-in-up {
    0% { 
      opacity: 0; 
      -moz-transform: translateY(20px); }
    100% { 
      opacity: 1; 
      -moz-transform: translateY(0); }
}

@-o-keyframes fade-in-up {
    0% { 
      opacity: 0; 
      -o-transform: translateY(20px); }
    100% { 
      opacity: 1; 
      -o-transform: translateY(0); }
}

_x000D_

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="content-block">  
  <div class="common-block">
    <h1 class="content-title">Scroll Down to Trigger the Animations...</h1>
    <div class="content-spacer"></div>    
    <ul class="column-group desktop-width-1of3 tablet-width-1of2 mobile-width-1of1">
      <li class="column responsive has-animation fade-in-up">
        <div class="relative width-1of1">
                    <div class="relative white-bg padding-bottom-1of1 width-1of1 overflow-hidden">
                      <div class="absolute-fill">
                            <div class="absolute-fill prepped-background" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" style="background-image: url('https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg');"></div><img class="absolute-fill opacity-0" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" srcset="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg">
                             </div>
                        </div>
                </div>
      </li>
      
      <li class="column responsive has-animation fade-in-up">
        <div class="relative width-1of1">
                    <div class="relative white-bg padding-bottom-1of1 width-1of1 overflow-hidden">
                      <div class="absolute-fill">
                            <div class="absolute-fill prepped-background" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" style="background-image: url('https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg');"></div><img class="absolute-fill opacity-0" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" srcset="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg">
                             </div>
                        </div>
                </div>
      </li>
      
      <li class="column responsive has-animation fade-in-up">
        <div class="relative width-1of1">
                    <div class="relative white-bg padding-bottom-1of1 width-1of1 overflow-hidden">
                      <div class="absolute-fill">
                            <div class="absolute-fill prepped-background" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" style="background-image: url('https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg');"></div><img class="absolute-fill opacity-0" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" srcset="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg">
                             </div>
                        </div>
                </div>
      </li>
      
      <li class="column responsive has-animation fade-in-up">
        <div class="relative width-1of1">
                    <div class="relative white-bg padding-bottom-1of1 width-1of1 overflow-hidden">
                      <div class="absolute-fill">
                            <div class="absolute-fill prepped-background" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" style="background-image: url('https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg');"></div><img class="absolute-fill opacity-0" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" srcset="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg">
                             </div>
                        </div>
                </div>
      </li>
      
      <li class="column responsive has-animation fade-in-up">
        <div class="relative width-1of1">
                    <div class="relative white-bg padding-bottom-1of1 width-1of1 overflow-hidden">
                      <div class="absolute-fill">
                            <div class="absolute-fill prepped-background" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" style="background-image: url('https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg');"></div><img class="absolute-fill opacity-0" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" srcset="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg">
                             </div>
                        </div>
                </div>
      </li>
      
      <li class="column responsive has-animation fade-in-up">
        <div class="relative width-1of1">
                    <div class="relative white-bg padding-bottom-1of1 width-1of1 overflow-hidden">
                      <div class="absolute-fill">
                            <div class="absolute-fill prepped-background" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" style="background-image: url('https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg');"></div><img class="absolute-fill opacity-0" data-src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" src="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg" srcset="https://www.tompetty.com/sites/g/files/g2000007521/f/sample_01.jpg">
                             </div>
                        </div>
                </div>
      </li>
      
    </ul>    
  </div>  
</div>

_x000D_

_x000D_

_x000D_

Answered By: Anonymous

Related Articles

  • Mobile browsers add a gap at the end of final element via…
  • How to parse the Manifest.mbdb file in an iOS 4.0 iTunes…
  • Show div on scrollDown after 800px
  • Why are CSS keyframe animations broken in Vue components…
  • JavaScript Code not running on a Live Sever nor Local Host
  • How to show title in hover - css / jquery
  • Having trouble with my nav bar/header, It used to work but…
  • How do i update a javascript variable as its value changes?
  • Is it possible to apply CSS to half of a character?
  • How to add 'load more' functionality to items on a page with…

Disclaimer: This content is shared under creative common license cc-by-sa 3.0. It is generated from StackExchange Website Network.

Post navigation

Previous Post:

Updating mongoose subSchema Object

Next Post:

WordPress is_tags not detecting tag clicked

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Get code errors & solutions at akashmittal.com
© 2022 Fix Code Error