Reputation: 369
I want call my function once when the statement if (scrollY > 100vh), but on every scroll when I get more than 100vh is calling func. I understand the reason why is that, but don't know how to fix that.
Perhaps it is simple but I can't do that.
I want a simple animation on scrolling.
code :
import anime from 'animejs';
var txt = document.querySelector('.textanimation');
txt.innerHTML = txt.textContent.replace(
/\S/g,
"<span class='letter'>$&</span>"
);
window.addEventListener('scroll', () => {
const vh = window.innerHeight;
const scrolled = window.scrollTop;
if (scrolled > vh) {
const scrollTextAnimation = anime.timeline();
scrollTextAnimation
.add({
targets: '.textanimation .letter',
translateY: [-100, 0],
easing: 'easeOutExpo',
duration: 1400,
delay: (el, i) => 30 * i
})
.add({
targets: '.textanimation',
duration: 1000,
easing: 'easeOutExpo',
delay: 1000
});
}
});
Upvotes: 0
Views: 655
Reputation: 1257
You can remove the event listener after your logic executes in order to stop it from ever firing again. You can do this in two ways:
1) Use the once
option as defined in the parameters for addEventListener
here. This option automatically removes the event listener after the event happens once. The OP has already stated this isn't working for them (possibly because the scroll needs to reach a certain height before the logic works so it is being removed too early).
2) Call removeEventListener
after the logic executes:
import anime from 'animejs';
var txt = document.querySelector('.textanimation');
txt.innerHTML = txt.textContent.replace(
/\S/g,
"<span class='letter'>$&</span>"
);
var animateOnce = function() {
const vh = window.innerHeight;
const scrolled = window.scrollTop;
if (scrolled > vh) {
const scrollTextAnimation = anime.timeline();
scrollTextAnimation
.add({
targets: '.textanimation .letter',
translateY: [-100, 0],
easing: 'easeOutExpo',
duration: 1400,
delay: (el, i) => 30 * i
})
.add({
targets: '.textanimation',
duration: 1000,
easing: 'easeOutExpo',
delay: 1000
});
// remove the event listener after the animation happens on the first time
window.removeEventListener('scroll', animateOnce);
}
}
window.addEventListener('scroll', animateOnce);
3) Here are a couple of other solutions in a post on sitepoint.
Upvotes: 0
Reputation: 369
I just added a bool that change the statement to false when I make a scrollY more than innerHeight/2. "Once" option in addEventListener was not working, don't know why. Is there a better solution how to fix that? The code below is working:
let myBool = true;
window.addEventListener('scroll', () => {
if (window.scrollY > window.innerHeight / 2 && myBool) {
anime.timeline()
.add({
targets: '.textanimation .letter',
translateY: [-100, 0],
easing: 'easeOutExpo',
duration: 1400,
delay: (el, i) => 30 * i
})
.add({
targets: '.textanimation',
duration: 1000,
easing: 'easeOutExpo',
delay: 1000
});
myBool = false;
}
});
Upvotes: 1
Reputation: 544
just add once option to the event listener to execute it one time.
window.addEventListener('scroll', () => {
const vh = window.innerHeight;
const scrolled = window.scrollTop;
if (scrolled > vh) {
const scrollTextAnimation = anime.timeline();
scrollTextAnimation
.add({
targets: '.textanimation .letter',
translateY: [-100, 0],
easing: 'easeOutExpo',
duration: 1400,
delay: (el, i) => 30 * i
})
.add({
targets: '.textanimation',
duration: 1000,
easing: 'easeOutExpo',
delay: 1000
});
}
}, {once: true});
Upvotes: 1