I wrote my own implementation of a declarative animation engine (i.e. the same timeline position always looks the same), but I'm pretty sure there are still a couple of bugs allowing you to go out of sync.
https://greensock.com/docs/v3/GSAP/Timeline
I hit a performance bug with greensock once and just quickly wrote my own simple animation framework, which I am using ever since, but I suppose it can be done better. I would think the native browser animation capability is superior?
https://rive.app/use-cases https://rive.app/blog/rive-as-a-lottie-alternative