【问题标题】:Trigger a CSS keyframe animation via scroll通过滚动触发 CSS 关键帧动画
【发布时间】:2016-04-29 12:35:22
【问题描述】:

假设我有一个带有动画的元素:

#element {
  animation: Fade 3s linear 1s forwards;
}

@keyframes Fade {
  /* do stuff */
}

如何仅在用户向下滚动时触发此动画? Vanilla JS、jQuery、ScrollMagic、GSAP/TweenMax,任你选择。

添加动画属性本身会触发效果吗?因此,用户滚动到某个点/元素,然后我应用类似:$('#element').css('animation', 'Fade 3s linear 1s forwards');?

【问题讨论】:

    标签: javascript jquery html css animation


    【解决方案1】:

    发布(并接受)的答案在技术上是正确的,但现在有更多性能友好的方法来实现这一点。如果要在多个元素上触发动画,则观看这些多个元素可能会导致性能不佳。请参阅example this question。免责声明:这个问题也有我的答案,我只会在这个anwser中复制我自己的工作:

    要以现代、高效的方式解决此问题,最好使用Intersection Observer (IO)

    使用 IO,您可以观察一个(或多个)元素,并在它们进入视野或它们相互交叉时做出反应。

    要使用 IO,您首先必须为其设置选项,然后定义要监视的元素,最后定义 IO 触发后究竟会发生什么。

    示例 (Taken from here),只做了一个最小的修改:即使动画还没有发生,作者也删除了 IO。我在检查元素是否可见时移动了 unobserve 调用。

    const SELECTOR = '.watched';
    const ANIMATE_CLASS_NAME = 'animated';
    
    const animate = element => (
      element.classList.add(ANIMATE_CLASS_NAME)
    );
    
    const isAnimated = element => (
      element.classList.contains(ANIMATE_CLASS_NAME)
    );
    
    const intersectionObserver = new IntersectionObserver((entries, observer) => {
      entries.forEach((entry) => {
        
        // when element's is in viewport,
        // animate it!
        if (entry.intersectionRatio > 0) {
          animate(entry.target);
          // remove observer after animation
          observer.unobserve(entry.target);
        }
      });
    });
    
    // get only these elements,
    // which are not animated yet
    const elements = [].filter.call(
      document.querySelectorAll(SELECTOR),
      element => !isAnimated(element, ANIMATE_CLASS_NAME)
    );
    //console.log(elements);
    
    // start observing your elements
    elements.forEach((element) => intersectionObserver.observe(element));
    .h100 {
    height: 100vh;
    }
    
    .watched {
     opacity: 0;
     transition: opacity .5s;
    }
    
    .watched.animated {
    opacity: 1;
    }
    <div class="h100">
    scroll down
    </div>
    <div class="watched">
    I'm watched
    </div>
    <div class="h100">
    Another element, keep scrolling
    </div>
    <div class="watched">
    I'm also watched
    </div>

    【讨论】:

      【解决方案2】:

      当用户向下滚动时,将一个类添加到具有动画的元素。

      伪代码

      on window scroll {
        if (scroll pos > x) {
          element.addclass("animateMe");
        }
      }
      

      演示

      http://jsbin.com/zuqexigepe/edit?html,output

      如果您希望每次用户滚动超过某个点时都发生动画,您可以简单地更改滚动事件以删除该类,如下所示:

      $(window).scroll(function () {
        if($(window).scrollTop() > 0) {
          element.addClass("animateMe");
        }
        else {
          element.removeClass("animateMe");
        }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-10
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        • 1970-01-01
        • 2021-02-06
        • 2015-08-11
        相关资源
        最近更新 更多