通过滚动触发CSS关键帧动画

4

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

#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');

2个回答

4
发布(并被接受)的答案从技术上讲是正确的,但现在有更加性能友好的方法来实现这一点。如果你想要触发多个元素上的动画,同时观察这些多个元素可能会导致性能不佳。例如,请参见此问题。免责声明:这个问题也有我的答案,我只会在这个答案中复制自己的工作:
为了以现代、高性能的方式解决这个问题,最好使用Intersection Observer (IO)
使用IO,可以观察一个(或多个)元素,并在它们进入视野或相互交叉时做出反应。
要使用IO,首先必须设置其选项,然后定义要观察的元素,最后定义IO触发时确切发生的事情。
示例(取自此处),进行了一个小修改:作者删除了即使动画还没有发生时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>


3

当用户向下滚动时,为具有动画效果的元素添加类。

伪代码

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接