Lottie-web: Control Bodymovin animation on mouse scroll according to page height

Created on 6 Jun 2017  路  14Comments  路  Source: airbnb/lottie-web

Hi. sorry, but this is more of my technical limit rather than the bodymovin's. but i have a question regarding something im trying to achieve.

I am trying to make my frame 1 of my animation at the top of my page, and final frame of animation at the bottom of a scrolling page. So when you scroll, the animation will animate and reach the last frame at the bottom.

I've manage to do the play on mousewheel part, but i cant figure out how to tie the start and end of animation depending on the height of the page.

here's what ive done so far (scroll on right side of page): http://fariskassim.com/stage/bodymovin/v1/index_mod.html

`

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');
    contentid = document.getElementById('contentid');

animLoaded();

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

    if (contentid.addEventListener) {
        contentid.addEventListener("mousewheel", MouseWheelHandler, false);
        contentid.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
    }else{
        contentid.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 < totalDuration) {
                val += (Math.abs(delta))*speed;
            }
        }else {
            if (val > 0) {
                val -= (Math.abs(delta))*speed;
            }
        }

        bodymovin.goToAndStop(val);
    }
}

`

Most helpful comment

sorry for the late replies. if you are referring to the one i did here:
https://www.fariskassim.com/stage/typojanchi/old_v1/

you can view the source and the code for what you want is there in the script tags.
but i'll just repost it here:

    var anim;
    var elem = document.getElementById('bodymovin')
    var animData = {
        container: elem,
        renderer: 'svg',
        loop: false,
        autoplay: false,
        rendererSettings: {
            progressiveLoad:false,
            preserveAspectRatio: 'xMidYMid slice'
        },
        path: 'data.json'
    };
    anim = bodymovin.loadAnimation(animData);

    $(window).scroll(function() {

        // calculate the percentage the user has scrolled down the page
        var scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height());


        console.log(anim.currentRawFrame);

        scrollPercentRounded = Math.round(scrollPercent);

        /*console.log( (scrollPercentRounded / 100) * anim.totalFrames );*/

        anim.goToAndStop( (scrollPercentRounded / 100) * 4000)
    });


Basically, i just measure the scroll position relative to scrollHeight of the scrollable div on the right in percentages.
Then with this percentage, i just use it to 'goToAndStop' on the frame of the animation.

All 14 comments

If I understand correctly, I think you need to measure the full height of your site and divide scrollTop by the height so you can sync the scroll to the animation.
If you have a codepen or some live link I can take a look.

here's a codepen. https://codepen.io/farisk/project/editor/ABaWqw/
ps. the live link was in the original post above

anyway i've managed to calculate the percentage of page scrolled. but im not sure how to apply it to the animation.
`

    $(window).scroll(function() {

        // calculate the percentage the user has scrolled down the page
        var scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height());

       console.log(scrollPercent)
    });

I've kinda solved it. dont have a pen for it but here is the live example :
http://fariskassim.com/stage/typojanchi/old_v1/

However i have a question.

In AE, i did the animation as a 60fps, 4 seconds. which means it should have 240 frames.
anim.totalFrames gives me 240 which is right.
but when i use anim.goToAndStop(240), it doesnt give me the last frame.
i have to use anim.goToAndStop(4000) to show the last frame. am i missing something here?

By default, the goToAndStop uses milliseconds as the first param.
You need to pass a second param as true in order to use frames.
so, if you try goToAndStop(240,true) it should work.

Ah thats what the 'ifFrame' was. Thanks!

hello, i want to apply this to my animation. Can you help me by sharing the code?

Hello,
I'm also wondering how to apply scroll into animation progress.
Would love to know how to do this

sorry for the late replies. if you are referring to the one i did here:
https://www.fariskassim.com/stage/typojanchi/old_v1/

you can view the source and the code for what you want is there in the script tags.
but i'll just repost it here:

    var anim;
    var elem = document.getElementById('bodymovin')
    var animData = {
        container: elem,
        renderer: 'svg',
        loop: false,
        autoplay: false,
        rendererSettings: {
            progressiveLoad:false,
            preserveAspectRatio: 'xMidYMid slice'
        },
        path: 'data.json'
    };
    anim = bodymovin.loadAnimation(animData);

    $(window).scroll(function() {

        // calculate the percentage the user has scrolled down the page
        var scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height());


        console.log(anim.currentRawFrame);

        scrollPercentRounded = Math.round(scrollPercent);

        /*console.log( (scrollPercentRounded / 100) * anim.totalFrames );*/

        anim.goToAndStop( (scrollPercentRounded / 100) * 4000)
    });


Basically, i just measure the scroll position relative to scrollHeight of the scrollable div on the right in percentages.
Then with this percentage, i just use it to 'goToAndStop' on the frame of the animation.

This has been very helpful, as I was able to implement the above solution and get some functionality out of it. However, in my scenario, my animation doesn't begin at the top of the page and end upon scrolling to the bottom.

I'm wondering how this can work if, for example, the animation begins 50% down the page and ends 60% down the page.

here's a codepen. https://codepen.io/farisk/project/editor/ABaWqw/
ps. the live link was in the original post above

anyway i've managed to calculate the percentage of page scrolled. but im not sure how to apply it to the animation.
`

    $(window).scroll(function() {

        // calculate the percentage the user has scrolled down the page
        var scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height());

       console.log(scrollPercent)
    });

Hi. can you please explain how you did it with the JSON file and images folder. If possible, please share code. Thanks.

A solution for everything https://lottiefiles.com/interactivity

sorry for the late replies. if you are referring to the one i did here:
https://www.fariskassim.com/stage/typojanchi/old_v1/

you can view the source and the code for what you want is there in the script tags.
but i'll just repost it here:

    var anim;
    var elem = document.getElementById('bodymovin')
    var animData = {
        container: elem,
        renderer: 'svg',
        loop: false,
        autoplay: false,
        rendererSettings: {
            progressiveLoad:false,
            preserveAspectRatio: 'xMidYMid slice'
        },
        path: 'data.json'
    };
    anim = bodymovin.loadAnimation(animData);

    $(window).scroll(function() {

        // calculate the percentage the user has scrolled down the page
        var scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height());


        console.log(anim.currentRawFrame);

        scrollPercentRounded = Math.round(scrollPercent);

        /*console.log( (scrollPercentRounded / 100) * anim.totalFrames );*/

        anim.goToAndStop( (scrollPercentRounded / 100) * 4000)
    });

Basically, i just measure the scroll position relative to scrollHeight of the scrollable div on the right in percentages.
Then with this percentage, i just use it to 'goToAndStop' on the frame of the animation.

Thanks 馃枻馃枻

A solution for everything https://lottiefiles.com/interactivity

woahh...Thank you ... that's what I was looking for 馃槈!

A solution for everything https://lottiefiles.com/interactivity

This doesn't appear to work for position: fixed though, like you have in your design, so I don't think the lottiefiles solution would actually work. Am I wrong?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yannieyeung picture yannieyeung  路  3Comments

casillasluisn12 picture casillasluisn12  路  4Comments

leantide picture leantide  路  3Comments

DannyK123456 picture DannyK123456  路  3Comments

processprocess picture processprocess  路  3Comments