Reputation: 61
How can I trigger this animation to start once in viewport?
<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; }
}
Upvotes: 4
Views: 15392
Reputation: 100
Or maybe you can use a more traditional way.
/* 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;
}
}
Usage
var item = document.getElementsByClassName("monster");
if(isInViewport(item)) {
item.classList.add("animation");
}
If you want to check it with scroll event
const monster = document.getElementsByClassName("monster");
/* Window Scrolling */
window.addEventListener("scroll", function(){
if(isInViewport(monster)) {
monster.classList.add("animation");
}
});
Upvotes: 0
Reputation: 17350
Use an IntersectionObserver
in javascript to detect when the element is on screen, then trigger the class that plays the animation like this (I changed your animation values since you wouldn't see them in a SO snippet):
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>
Upvotes: 10