I'm trying to use ScrollMagic to control a TimelineMax which moves the playhead of a Lottie animation.
So, as the user scrolls, the animation plays relative to the speed and direction of the scroll. I'm so close and need a little help to bring the effect home.
First, I include my Libraries
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.5.9/lottie.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/animation.gsap.js"></script>
Then...
// init scrollmagic
var controller = new ScrollMagic.Controller();
Now, the animation setup...
// Manage Animation
var animation = bodymovin.loadAnimation({
container: document.getElementById('lottie'), // Required
path: '/static/animations/animation.json', // Required
renderer: 'svg', // Required
loop: false, // Optional
autoplay: false, // Optional
name: "Welcome to Awesomeness", // Name for future reference. Optional.
});
This is where I'm struggling:
// Setup Timeline
var lottieControl = new TimelineMax({ repeat: -1, yoyo: true }); // <-- don't loop and let the timeline go back and forth
lottieControl.to({ frame:0 }, 1, { // <-- is this right? I'm telling the timeline to start at frame 0
onUpdate:function(){
animation.goToAndStop(Math.round(this.target.frame), true) // <-- move the playback head of the animation to the target frame that has been rounded and use frames not time (true)
},
ease:Linear.easeNone
})
Finally, bring it all back together...
// Attach to scroll
var lottieScene = new ScrollMagic.Scene({
duration: '80%',
offset: 1
})
.setPin("#header-scroll")
.setTween(lottieControl)
.addTo(controller);
For the life of me, I can't see if I'm using the goToAndStop
method right or not. Thanks for your time.
After hours of testing I found the answer. I was looking at the wrong thing. I needed to tie the timeslines progress to the frame to go to. In this instance, there are 300 frames, thus the multiplication by the number of frames in the animation.
Here's the revised code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.5.9/lottie.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/animation.gsap.js"></script>
<script>
// init scrollmagic
var controller = new ScrollMagic.Controller();
// Manage Animation
var animation = bodymovin.loadAnimation({
container: document.getElementById('lottie'), // Required
path: '/static/animations/scroll_animation.json', // Required
renderer: 'svg', // Required
loop: false, // Optional
autoplay: false, // Optional
name: "Welcome to Awesomeness",
});
// Setup Timeline
var tl = new TimelineMax();
tl.to({frame:0}, 1, {
frame: animation.totalFrames-1,
onUpdate:function(){
animation.goToAndStop((Math.round(this.progress() * 300)), true)
},
ease: Linear.easeNone
})
// Attach to scroll
var lottieScene = new ScrollMagic.Scene({
duration: '100%',
offset: 1
})
.setPin("#header-scroll")
.setTween(tl)
.addTo(controller);
</script>