一个一个地动画元素

Animating Elements in One by One

我正在尝试制作一个滚动 jQuery 序列,当元素在视图中时,它一个接一个地为元素设置动画。 Here is my CodePen 这是代码:

$(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');

});

我有它,所以当元素滚动到视图中时,class“.has-animation”被替换为“.animated”和“.in-view”。元素样式“visibility”也从隐藏变为可见。

目前,当元素到达视点时,它们会同时进入动画,而不是每个元素依次进入动画。

我已尝试替换此代码中的 $element:

$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));
        
});

使用 $animatedItem 所以它看起来像这样:

$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));
        
});

这段代码($animatedItem 代码)实际上实现了我正在寻找的功能,但是,元素在滚动时立即设置动画,而不是在到达视点时加载。这让我相信像这样的函数应该指向 $animatedItem 但在我的代码开头附近?

我是 JS/JQuery 的新手(自学),我在解决这个问题时遇到了一些麻烦,非常感谢您的帮助!谢谢大家!

关键是时机。

一旦某些元素得到 in-view,删除 has-animation class... 然后,设置 timeout 用于触发 CSS 动画。

此外,您必须刷新 $animatedItem collection... ;)

此答案的结果最好在 CodePen

中查看

$(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");
});
/*-----------------------------------------*/
/* 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); }
}
<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>