如何触发此动画在视口中启动一次?
<div class="monster"></div>
.monster {
width: 200px;
height: 200px;
margin: -50px auto;
background: url('/wp-content/uploads/2021/07/sprite1.png') left center;
animation: play 2.8s steps(15);
animation-iteration-count: 1
}
@keyframes play {
100% { background-position: -3000px; }
}
在javascript中使用IntersectionObserver
来检测元素何时在屏幕上,然后触发播放动画的类,如下所示(我更改了您的动画值,因为您在SO片段中看不到它们(:
const element = document.querySelector('.monster');
const observer = new IntersectionObserver(entries => {
element.classList.toggle( 'animation', entries[0].isIntersecting );
});
observer.observe( element );
.monster {
width: 200px;
height: 200px;
margin: 0 auto;
background: black;
}
main {
margin: 1000px auto;
}
@keyframes play {
100% { background: red; }
}
.animation {
animation: play 2.8s steps(15);
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.monster:after {
position: fixed;
content: 'Keep scrolling!';
left: 50%;
top: 50%;
opacity: 0;
transform: translate(-50%,-50%);
transition: opacity .4s;
}
.monster:not(.animation):after {
opacity: 1;
}
<main>
<div class="monster"></div>
</main>
或者您可以使用更传统的方式。
/* If Item is in Viewport */
function isInViewport(item) {
var bounding = item.getBoundingClientRect(),
myElementHeight = item.offsetHeight,
myElementWidth = item.offsetWidth;
if(bounding.top >= -myElementHeight
&& bounding.left >= -myElementWidth
&& bounding.right <= (window.innerWidth || document.documentElement.clientWidth) + myElementWidth
&& bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) + myElementHeight) {
return true;
} else {
return false;
}
}
使用
var item = document.getElementsByClassName("monster");
if(isInViewport(item)) {
item.classList.add("animation");
}
如果你想用滚动事件进行检查
const monster = document.getElementsByClassName("monster");
/* Window Scrolling */
window.addEventListener("scroll", function(){
if(isInViewport(monster)) {
monster.classList.add("animation");
}
});