Reputation: 101
This script uses intersection observer to look for anything with the class ".anim-target" and then looks to see if it also contains another class ("anim-target-NAME") that tells it which class to add. Then it removes it once it's out of view so it can re-animate again. Is there a more concise way to write it without relying on individual IF statements?
document.addEventListener("DOMContentLoaded", function(event) {
observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
if (entry.target.classList.contains('anim-target-fadeIn')) {
entry.target.classList.add('animated', 'fadeIn');
}
if (entry.target.classList.contains('anim-target-fadeInUp')) {
entry.target.classList.add('animated', 'fadeInUp');
}
if (entry.target.classList.contains('anim-target-bounceIn')) {
entry.target.classList.add('animated', 'bounceIn');
}
if (entry.target.classList.contains('anim-target-zoomIn')) {
entry.target.classList.add('animated', 'zoomIn');
entry.target.style.opacity = 1;
}
}
else {
entry.target.classList.remove('animated', 'fadeIn', 'fadeInUp', 'bounceIn', 'zoomIn');
entry.target.style.opacity = 0;
}
});
});
document.querySelectorAll('.anim-target').forEach(image => {
observer.observe(image);
});
});
Upvotes: 1
Views: 106
Reputation: 12208
Consider making your code DRYer:
DRY:
let animArr = ["animated"]
let etcl = entry.target.classList
if (etcl.contains("anim-target-fadeIn")) {
animArr.push(["fadeIn"])
}
if (etcl.contains("anim-target-fadeInUp")) {
animArr.push(["fadeInUp"])
}
if (etcl.contains("anim-target-bounceIn")) {
animArr.push(["bounceIn"])
}
if (etcl.contains("anim-target-zoomIn")) {
animArr.push(["zoomIn"])
entry.target.style.opacity = 1;
}
etcl.add(...animArr)
Even DRYer:
let animStyles = ["fadeIn","fadeInUp","bounceIn","zoomIn"]
let et = entry.target
let animArr = []
animStyles.forEach(style => {
if(et.classList.contains("anim-target-" + style)){
animArr = animArr.concat(["animated", style])
}
}
et.style.opacity = et.classList.contains("anim-target-zoomIn") ? 1 : 0
et.classList.add(...animArr)
Upvotes: 1
Reputation: 206669
.anim
and the desired animation-type class. classList.toggle()
to toggle/trigger the .animated
class:const animEntry = (ent) => ent.target.classList.toggle('animated', ent.isIntersecting);
const animObserve = () => {
const observer = new IntersectionObserver(ents => ents.forEach(animEntry));
document.querySelectorAll('.anim').forEach(el => observer.observe(el));
}
document.addEventListener("DOMContentLoaded", animObserve);
.anim {
height: 50vh;
width: 50vh;
background: #f48024;
position: relative;
transition: 1.2s;
margin: 500px auto;
}
.fadeIn {opacity:0;}
.fadeIn.animated {opacity:1;}
.fadeInUp {opacity:0; transform: translateY(100%); }
.fadeInUp.animated {opacity:1; transform: translateY(0%);}
.zoomIn {transform: scale(0);}
.zoomIn.animated {transform: scale(1);}
.rotateCW {transform: rotate(0deg);}
.rotateCW.animated {transform: rotate(1turn);}
Scroll down...
<div class="anim fadeIn">fadeIn</div>
<div class="anim fadeInUp">fadeInUp</div>
<div class="anim zoomIn fadeIn">zoomIn & fadeIn</div>
<div class="anim rotateCW">rotateCW</div>
Upvotes: 1
Reputation: 1
You can replace
if (entry.target.classList.contains('anim-target-fadeIn')) {
entry.target.classList.add('animated', 'fadeIn');
}
if (entry.target.classList.contains('anim-target-fadeInUp')) {
entry.target.classList.add('animated', 'fadeInUp');
}
if (entry.target.classList.contains('anim-target-bounceIn')) {
entry.target.classList.add('animated', 'bounceIn');
}
if (entry.target.classList.contains('anim-target-zoomIn')) {
entry.target.classList.add('animated', 'zoomIn');
entry.target.style.opacity = 1;
}
with
var classList = entry.target.classList;
entry.target.classList.add('animated', classList.split('-')[2]);
if (classList.contains('anim-target-zoomIn')) {
entry.target.style.opacity = 1;
}
Upvotes: 2