假设我有一个带动画的元素:
#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');
的内容?
答案 0 :(得分: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");
}
});
答案 1 :(得分:1)
发布(并接受)的答案在技术上是正确的,但是如今,有更多性能友好的方法可以实现此目的。如果要在一个以上的元素上触发动画,则观看这些多个元素可能会导致性能下降。参见example this question。免责声明:这个问题也有我的答案,我只会在此答案中复制自己的作品:
要以一种现代,高性能的方式解决此问题,最好为此使用Intersection Observer (IO)。
使用IO,您可以观察一个(或多个)元素并在它们出现或彼此相交时做出反应。
要使用IO,您首先必须为其设置选项,然后定义要监视的元素,最后定义一旦IO触发将发生什么情况。
示例(Taken from here),进行了最小的修改:即使动画尚未发生,作者也删除了IO。我将unobserve调用移到了check元素是否可见的内部。
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>