Jump to content
Search Community

TimelineMax + ScrollMagic + Lottie-web (Bodymoving). Is it possible, is it necessary?

andrewnelson test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I have recently started working with an animator who uses After Effects and the Bodymovin plugin to create SVG animations for websites. Bodymovin exports the SVG file as a JSON file, which you then run in a div via a JavaScript command from the lottie.js, Lottie Web library. (Check out the links, or scroll down further in this post for more details.)

 

My primary goal is to create a workflow that allows for rapid creation of custom SVG animations, and be able to control them fully with GreenSock and ScrollMagic.

During my research and attempts to integrate them all I have wondered how much of these JS libraries are overlapping each other in toolkits and effectiveness. My knowledge of anything past design, UI/UX, and basic front end JavaScript starts to become limited. So I have to ask, is it possible to control the GreenSock + Lottie animation using ScrollMagic? And perhaps more importantly, should I be animating using this workflow at all?

 

Current Progress:

 

 

-------------------------------

 

If you're interested in seeing my initial journey to get all 3 integrated I have documented it below...

(Unfortunately I don't have CodePen pro so I wasn't able to put this all together in a Pen for viewing, if it's something that becomes necessary I will go ahead and get CodePen pro and do so.)

 

 

Research: Integrating TimelineMax, with Lottie Web, and Controlling w/ ScrollMagic

 

I have recently started working with an animator who uses After Effects and the Bodymovin plugin to create SVG animations for websites. Bodymovin exports the SVG file as a JSON file, which you then run in a div via a JavaScript command from the lottie.js, Lottie Web library as you can see from the sample below.


 

var select = function(s) {
    return document.querySelector(s);
  },
  selectAll = function(s) {
    return document.querySelectorAll(s);
  },
  animationWindow = select('#animationWindow'),
    animData = {
      container: animationWindow,
      renderer: 'svg',
      loop: true,
      autoplay: true,
      path: 'PATH.JSON'
    }, anim;

var anim = lottie.loadAnimation(animData);

 

 

A Singular Example of Controlling Lottie w/ GreenSock

 

I have been looking high and low for documented of examples of people successfully integrating with GreenSock and Scroll Magic with very limited results. I have found one excellent video on YouTube of a dev by the name Chris Gannon (who I suspect may be a member of these forums) successfully controlling a Lottie animation through TimelineMax but that is about it. 

 

 

 

 

My Attempts to Recreate This, and Add ScrollMagic Control

 

Have not gone very well... I believe that the current state of my code (mostly able to get this far thanks to the work of Chris Gannon) is missing some vital information on the Lottie animation itself.

 

  • How many frames does the animation have?
  • The relation of scroll position to frame selection.
  • Pushing that data through to TimelineMax to effectively control animation.

 

My goal being to control the animation with a Tween, Duration Tween, or a Reversed Tween.

 

The code below is my hack-job trying to get this all working; i'm currently dealing with an error from this code "Uncaught ReferenceError: animationControl is not defined".

 

jQuery(function($) {

    //Lottie animation Window and Data wrapper
    var select = function(s) {
        return document.querySelector(s);
      },
      selectAll = function(s) {
        return document.querySelectorAll(s);
      },
      animationWindow = select('#animationWindow'),
        animData = {
                container: animationWindow,
            renderer: 'svg',
            loop: true,
            autoplay: true,
            path: 'PATH.JSON'
            }, anim;

    //Lotie animation trigger
    var anim = lottie.loadAnimation(animData);
    anim.setSpeed(1);

    //TimelineMax Lottie animation control
    $('#animationWindow').each(function(){
        var animationControl = new TimelineMax({});
        animationControl.to({frame:0}, 4, {
            frame:anim.totalFrames-1,
            onUpdate:function(){
                anim.goToAndStop(Math.round(this.target.frame), true)
            },
            repeat: -1,
            yoyo: true,
            ease:Linear.easeNone
        })
    });

    //ScrollMagic Scene
    var controller = new ScrollMagic.Controller();

    var icon_scene = new ScrollMagic.Scene({triggerElement: "#animationWindow_trigger", triggerHook: 'onEnter'})
        .setTween(animationControl)
        .addTo(controller);
  
});

 

 

And this is my current state of affairs. I will be updating this post as I move along, and eventually - hopefully come up with an elegant solution to this.

  • Like 2
Link to comment
Share on other sites

Welcome to the forums!

 

I'm not very familiar with Bodymovin' or ScrollMagic so I may not be able to help much but I can tell you with confidence that what you're attempting is totally doable. 

 

The problem I noticed in your code is that you've got "animationControl" as a local variable tucked inside of that function you're feeding to $.each(), thus it's not available outside that function. It's a scope issue. 

 

What's confusing to me is that it looks like you've got it set up to accommodate MULTIPLE #animationWindow instances (which of course can't happen because IDs by their very nature are unique), so why do you have things inside of an $.each() at all? It doesn't even look like you're referencing the #animationWindow element at all inside that loop, so couldn't you just delete the whole $('#animationWindow').each(function(){ ... }) wrapper?

 

Oh, and you don't need to sign up for Codepen Pro to do a codepen example. It's free to create anonymous pens. See 

 

Good luck with the project & happy tweening!

  • Like 2
Link to comment
Share on other sites

Thanks for the welcome, and for the quick reply! I have to say I love the community here and have learned so much from you and your team!

Re: your post

 

19 minutes ago, GreenSock said:

What's confusing to me is that it looks like you've got it set up to accommodate MULTIPLE #animationWindow instances (which of course can't happen because IDs by their very nature are unique), so why do you have things inside of an $.each() at all? It doesn't even look like you're referencing the #animationWindow element at all inside that loop, so couldn't you just delete the whole $('#animationWindow').each(function(){ ... }) wrapper?

 

I copied and pasted the nearest usable function while trying to patch this together (my ability to write code from scratch isn't that great). In this example it is the only ID of its type so I assumed it would have been good enough for testing purposes -- that being said I should have been more thoughtful about it when posting the code here. I'll make sure to fix that when posting the solution.
 

21 minutes ago, GreenSock said:

The problem I noticed in your code is that you've got "animationControl" as a local variable tucked inside of that function you're feeding to $.each(), thus it's not available outside that function. It's a scope issue. 

 

Between this insight, some more reading, and fresh eyes, hopefully I'll be able to post some positive results tomorrow!

 

And regarding the CodePen, the dependencies for running the Lottie animations with the JSON files made it hard enough to get GSAP,  and Lottie running on the same Pen that I just decided to do the testing on my web server. I'll take another peak at it tomorrow and see if I can't find a way to get all the dependencies running on the pen.

  • Like 1
Link to comment
Share on other sites

Update #1: A Starter Pen Template: TimelineMax and ScrollMagic working together, and Lottie running an SVG animation independently.

 

I did have to go PRO with CodePen to be able to load the JSON SVGs into the Pen; I couldn't find a way around it. (I spent a good 2 hours trying to hack together a free alternative.)

 

See the Pen aGQGxQ by anothercreativeltd (@anothercreativeltd) on CodePen

Link to comment
Share on other sites

Update #2: GSAP is wrapping Lottie, and the animation is being triggered by Scroll Magic.

 

I have been able to get the most basic of functionality of Lottie working with ScrollMagic + GSAP. Once the ScrolLMagic scene is triggered and command to .play() the lottie scene is run.

 

I believe the next step in this process will be figuring out how ScrollMagic and GSAP pass commands to each other, and then passing that information through and converting it to something Lottie understands to get it perform more like a GSAP timeline tween.

This is very quickly leaving my scope of knowledge so moving forward from here will take some time indeed! If anyone has any suggestions or wants to jump in on the pen help is much appreciated!

 

See the Pen pVQZbm by anothercreativeltd (@anothercreativeltd) on CodePen

 

Link to comment
Share on other sites

10 hours ago, andrewnelson said:

I believe the next step in this process will be figuring out how ScrollMagic and GSAP pass commands to each other, and then passing that information through and converting it to something Lottie understands to get it perform more like a GSAP timeline tween.

 

There is no passing of commands between GSAP and ScrollMagic. GSAP has no concept of ScrollMagic. It doesn't exist as far as GSAP is concerned. And Lottie is just a fancy flip book animation. Tell it what frame to display, and it displays that frame.

 

Maybe it's best to take a step back, and first understand how some of this stuff works conceptually. Please watch these 3 videos. It will only take like 10 minutes, and is key to understanding how a lot animation works.

 

Normalization - https://www.youtube.com/watch?v=hJqRcExiBk0

Linear interpolation - https://www.youtube.com/watch?v=mAi2-LTC2CA

Map - https://www.youtube.com/watch?v=FxAEXHGZSPA

 

 

All GSAP animations have a start and end value. It changes the value using interpolation. The norm value is time.  The normalized time value is the same thing as the progress value. 

https://greensock.com/docs/TweenLite/progress()

 

ScrollMagic does the same thing as GSAP, but instead of using time for the norm value, it uses the scroll position. So scroll position can also be considered a progress value.

 

So here's the connection.

ScrollMagic can change the progress of a GSAP animation.

A GSAP animation can change a frame value.

Lottie can be controlled by specifying a frame number.

 

GSAP can't control the frame value of a Lottie animation directly, but you can animate a frame value on a generic object. Every time GSAP updates that object, you take the frame value, round it, and pass it into Lottie.

 

See how it works on it's own.

 

See the Pen gzZvJW by osublake (@osublake) on CodePen

 

 

You shouldn't be calling .play() on your Lottie animation inside an onUpdate callback as it will constantly call it. The reason your animation isn't working like it should is because you omitted the most important part. You can't animate something if it doesn't exist. You have to wait for .json file to download and processed by the player. Look at the onDOMLoaded function in that video. That's kind of important.

 

  • Like 6
Link to comment
Share on other sites

Concerning your first question about library overlap, look at what I wrote about ScrollMagic in my previous post.

 

39 minutes ago, OSUblake said:

ScrollMagic does the same thing as GSAP, but instead of using time for the norm value, it uses the scroll position. So scroll position can also be considered a progress value.

 

 

I have always claimed that ScrollMagic isn't needed, and it isn't. You can do the same exact thing by specifying the scroll position for an animation's time/duration. Nothing magical.

 

See the Pen a633d0c9e6e2b951496d7f1eb4fd8fb6 by osublake (@osublake) on CodePen

 

 

 

 

  • Like 7
Link to comment
Share on other sites

Update #3: Lottie Animation is being controlled by GSAP, with basic functionality.

 

@OSUblake thanks again for all the information! I have been on a learning spree today and your insights have been invaluable. 

So I think this is mostly done; although I imagine it's not very well optimized code. Trigger Tweening, and Duration Tweening both work. I haven't put the code through any stress tests to see how easily it breaks yet.

 

See the Pen odJKed by anothercreativeltd (@anothercreativeltd) on CodePen

 

 

  • Like 1
Link to comment
Share on other sites

  • 1 year later...

Hello guys. 

 

I have followed the tutorial really close. I've been trying to implement this animation in a vue.js project with my own animation. the animation gets loaded with success. but when it comes to controlling the frames with GreenSock i get the follow errors. 

 

image.png.a49bbe5251788a329fa7a96d9a0df7c8.png

 

in the goToAndStop function the parameter "this.target.frame" is returning property of undefined.

When i console.log(this) it does reffer to the TimelineMax() object. but my TimeLineMax() object  doesnt contain  a target object. 

 

How can i reference the frames that are being used in the tl.to() ?

 

Thanks in advance

 

 

Link to comment
Share on other sites

10 hours ago, Youssef said:

in the goToAndStop function the parameter "this.target.frame" is returning property of undefined.

When i console.log(this) it does reffer to the TimelineMax() object. but my TimeLineMax() object  doesnt contain  a target object. 

 

How can i reference the frames that are being used in the tl.to() ?

 

We don't even know what version of gsap you are using. If you're using v3, you should use gsap.timeline() instead of new TimelineMax().  And tweens have a targets() method.

https://greensock.com/docs/v3/GSAP/Tween/targets()

 

But I never inlined an object like that, so why are you? 

 

See the Pen be8cf895aa9cd6aeac90cb6892f6f235 by osublake (@osublake) on CodePen

 

 

 

 

 

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...