Thanks everyone for the replies and ideas.
Probably should have been clearer in my initial post (sorry about that) because I just wanted to bring a potential bug to attention quickly, but yes, indeed, I want animation to happen only once, with scrubbing that has custom delay, and only in forward direction.
This does work but only if if you are going forward direction. If you position your scroll after the trigger, refresh, and scroll upwards, it will be animating backwards. This is not an issue with the original Codepen approach because upon page reload it "skips" the animation because scroll position is past trigger area.
As a workaround I ended up with something ridiculous like this. onComplete callback on Tweens does not provide scroll progress/direction, which made things quite wrangled for inexperienced me. The rather forceful delayed self.kill with setTimeout is there for when onLeave gets triggered on page load.
const CharacterTween = gsap.from("#character", {
filter: "blur(20px) grayscale(30%)",
opacity: 0,
autoRound: false,
lazy: false
});
const CharacterScrollTrigger = ScrollTrigger.create({
animation: CharacterTween,
trigger: "#character",
start: "top 70%",
end: "bottom 80%",
scrub: 0.45,
onLeave: self => {
if (self.progress === 1 && self.direction === 1) {
self.getTween().eventCallback("onComplete", event => {
self.kill(false)
})
try {
setTimeout(() => {
self.kill(false)
}, 500)
} catch (e) {
console.error(e)
}
}
},
});
CharacterTween.eventCallback("onComplete", function() {
CharacterTween.kill(false)
CharacterScrollTrigger.kill(false)
});
Let me know if you know a better way than this one. Thanks!