Lottie-web: Playhead control

Created on 24 Nov 2015  路  14Comments  路  Source: airbnb/lottie-web

Curious if there is anything like the following is in place:

animation.goToAndPlay( 24 );          // Frame
animation.goToAndPlayPerc( 0.5 );     // Percentage
animation.goToAndPlayMarker( "4" );   // After Effects Composition marker

animation.goToAndStop( 24 );             // Frame
animation.goToAndStopPerc( 0.5 );        // Percentage
animation.goToAndStopMarker( "start" );  // After Effects Composition marker

I'd like to help out / create pull request, but as I look at the source code, there are a few things I'm not sure I follow. Maybe a few comments or documentation would help with collaboration. Thanks again, love the project!

All 14 comments

@Tolmark12 There is a goToAndStop that accepts milliseconds or frames.
percentage should be easy to implement. I'll take a look at it.
Markers is not as simple, because composition markers are not exposed to scripting unfortunately. I'm looking into using a layer's markers as reference.

Documentation is coming. Hopefully before the end of the year. I need to finish some features first.

@bodymovin Is there any function that can tell me the total number of frames in an animation? I am hoping to tie the svg playback to mousewheel scroll, and I can use goToAndStop to dynamically cycle through the next 'x' number of frames, based on scroll distance. But it would be great to know when I've reached the last frame so that I can do other things.

Maybe you've already thought about animation based on mousewheel scroll, and have a better solution to my question above?

@kirillminiaev there is not an official API that will get you the number of frames, but the anim instance has an exposed property "totalFrames" that holds that value.
I haven't considered specifically mousewheel as a "timeline" for the animation, but yes, in the future, using something else than the current time, like a swipe gesture, is on my pipeline.

@bodymovin Hmmm, doing bodymovin.totalFrames doesn't yield anything. Do I need to do something else specifically to get the anim instance?

Also, about done with a quick mousewheel script I will post here that does what I want. Its not thoroughly tested, but might be worth something :)

@bodymovin Never mind. Found how to access the variable.

@kirillminiaev totalFrames is a property of an animation instance, not the library itself.
How are you instantiating your animation?

@bodymovin So here is what I came up with as a quick test/proof-of-concept:

<script>
    var animData = {
        wrapper: document.getElementById('bodymovin'),
        animType: 'svg',
        loop: false,
        prerender: true,
        autoplay: false,
        path: 'data.json'

    };
    var anim = bodymovin.loadAnimation(animData),
        container = document.getElementById('bodymovin');

    animLoaded();

    function animLoaded() {
        if (!anim.isLoaded) {
            setTimeout("animLoaded();", 1000);
            return;
        } else {
            attachScroll(anim, container, 50);
        }
    }
    function attachScroll(anim, container, speed) {
        var val = 0,
            totalFrames = anim.totalFrames*anim.frameRate;

        if (container.addEventListener) {
            container.addEventListener("mousewheel", MouseWheelHandler, false);
            container.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
        }else{
            container.attachEvent("onmousewheel", MouseWheelHandler);
        }

        function MouseWheelHandler(e) {
            var e = window.event || e;
            var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
            if (delta < 0) {
                if (val < totalFrames) {
                    val += (Math.abs(delta))*speed;
                }
            }else {
                if (val > 0) {
                    val -= (Math.abs(delta))*speed;
                }
            }

            bodymovin.goToAndStop(val);
        }
    }
</script>

This replaced the <script> tag in your bodymovin demo page. Maybe there is a better way to figure out when an animation has loaded? Maybe you already have an event listener for animation loaded state?

@kirillminiaev yes there is an event "data_ready" you can hook to

@bodymovin Just got back to this. I'm trying to do this:

var anim = bodymovin.loadAnimation(animData),
        container = document.getElementById('bodymovin');

anim.addEventListener("data_ready", attachScroll(anim, container, 50));

And it's not quite working. Am I linking to the event correct?

@kirillminiaev try:

anim.addEventListener( "data_ready", function(){
  attachScroll(anim, container, 50);
})

@Tolmark12 Perfect. Thank you!

@kirillminiaev

Thank you for your code above. I'm trying to do something similar.
Just one thing I noticed:

totalFrames = anim.totalFrames*anim.frameRate;

I think you might mean

totalDuration = anim.totalFrames/anim.frameRate*1000

In your code example, it only shows part of the animation.

If use time in goToAndStop, the first param is in milliseconds.

@jjhan1986 Thank you for the catch!

Thanks, @kirillminiaev @jjhan1986 It should be updated in docs.

If use time in goToAndStop, the first param is in milliseconds.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cpdt picture cpdt  路  4Comments

yannieyeung picture yannieyeung  路  3Comments

zhengs picture zhengs  路  3Comments

Ipaulsen picture Ipaulsen  路  4Comments

leantide picture leantide  路  3Comments