Okay Jon!
I think I found a way to do what you want to achieve.
Here’s how to programmatically pause and play your lotties ON the cards depending if they are visible or not.
Just FYI:
First you need a way to access the lottie library since it’s bundled inside the WF internals.
This code will reinitialize the lottie library to a globally scoped variable, which you can directly access:
const lottie = Webflow.require('lottie').lottie;
Now you can get all previously registered animations with this line
const animations = lottie.getRegisteredAnimations();
I found this snippet from @Jarek, which waits for the .jsons files to be loaded and parsed. I have modified it to work with your use-case.
Place this code possibly where you have your other jquery code (at the end of the body):
<script>
var lottie, animations
// Return a promise that resolves to true once animation is loaded
async function animationLoaded(animation) {
if(animation.isLoaded) {
return true
}
return new Promise((resolve, reject) => {
animation.addEventListener('DOMLoaded', () => {
resolve(true)
})
})
}
// Return a promise that resolves to true once all animations are loaded
async function waitForAnimationsLoaded(animations) {
await Promise.all(animations.map(animationLoaded))
}
async function initAnimations() {
lottie = Webflow.require('lottie').lottie
animations = lottie.getRegisteredAnimations()
await waitForAnimationsLoaded(animations)
}
var Webflow = Webflow || []
Webflow.push(() => {
initAnimations()
.then(() => {
console.log('Initialized animations')
// hide splash screen
})
.catch((error) => {
console.error(error)
})
})
</script>
You can now use lotties global methods like lottie.freeze()
on the global scope!
If you take a look at the contents of animations
you will see an array of all animations lottie found on your site:
You can target specific animations via animations[X].isPaused = true
to pause them or unpause them with false
.
If you hardcode the indexes of the animationItems and later on insert a new lottie somewhere, be aware, this WILL mess with the targeting.
Usually one could directly target each animation controls by setting the custom attribute data-name
on the lottie element in the WF designer, however - this doesn’t work for me.
You can give individual animations a name, still:
animations[X].name = 'NAME'
// and then
lottie.stop('NAME')
// OR
lottie.play('NAME')
Have a look at the properties and methods of either the lottie object (e.g. addressing all animations) or the individual animation object. They have different intents and purposes!
BUTT, HERE’S THE CATCH
All these things ONLY work on lottie elements that DO NOT have additional interactions set, like scroll into view etc…
As soon as you add your own interactions on the lottie element in the designer, this will not work anymore. The interactions simply override the reinitiated behaviour we have set here. I didn’t look into the internals too much, so I’m not sure.
If you need functionality like scroll into view, etc. you could however resort back to implementing your own intersectionObserver via the browsers API.
I hope this helps you a bit, feel free to ask if you get stuck!