Jump to content
Search Community

Synchronize containerAnimation elements

Captain W test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

Hello fine folks with a single green sock on,

I've scratched my head a bit on this one and found no remedy but call upon you.

So here I have a horizontal animation that consists in a moving backdrop (data-background) with a series of absolutely positioned items (data-tag) atop. So far so good.

What I need now is animating the tags when they enter the scene (here a simple class addition -> I didn't use toggleClass on purpose by the way), i.e. when they reach the containerAnimation defined zone (as per the official example

See the Pen WNjaxKp by GreenSock (@GreenSock) on CodePen

).

I am able to do it but I don't understand how to combine the simple horizontal movement (my animateTags() function) + the scrollTrigger that is passed to each tag. First I thought I could do it in a single gsap.to() but it didn't work and so I attached the two of these to all tags, expecting them to run at the same time thanks to timeline.add(..., 0) but it doesn't seem to fit the bill. As the markers show the tags and their respective triggers' movement keep drifting.

My question is then the following: how can I combine both gsap.to() in a single call or how can I synchronize both movements?

Thank you in advance!

By the way you'll have to open the pen in Codepen because in this iframe the tags are not visible.

See the Pen abQXNre by klprt (@klprt) on CodePen

Link to comment
Share on other sites

  • Solution

Hi,

 

I see two issues in your setup, first your tag animations that should be controlled by the container animation don't have any property that GSAP should animate:

tags.forEach((tag, index) => {
  superTimeline.add(
    gsap.to(tag, {
      scrollTrigger: {
        id: tag.id,
        containerAnimation: superTimeline,
        start: "center 80%",
        end: "center 20%",
        trigger: tag,
        onEnter: () => {
          tag.classList.add("tag-visible");
        },
        markers: true
      }
    })
  , 0);
});

They have just a ScrollTrigger configuration and no animation will happen because of these instances. Also you are adding every single instance at 0 seconds so all of them will start at the same time but at the same time you are passing start and end points.

 

Second, you are adding these instances to the superTimeline, which at the same time is being used as the container animation property. That's logically impossible, since every time you add an instance to the timeline the timeline duration gets longer and therefore the ScrollTrigger calculations get really messy. On top of that you are nesting single tween instances with ScrollTrigger configuration to a Timeline that also has a ScrollTrigger configuration, that is another logical pickle that will create more issues down the road:

 

Nesting ScrollTriggers inside multiple timeline tweens

very common mistake is applying ScrollTrigger to multiple tweens that are nested inside a timeline. Logic-wise, that can't work. When you

nest an animation in a timeline, that means the playhead of the parent timeline is what controls the playhead of the child animations (they all must be synchronized otherwise it wouldn't make any sense). When you add a ScrollTrigger with scrub, you're basically saying "I want the playhead of this animation to be controlled by the scrollbar position"...you can't have both. For example, what if the parent timeline is playing forward but the user also is scrolling backwards? See the problem? It can't go forward and backward at the same time, and you wouldn't want the playhead to get out of sync with the parent timeline's. Or what if the parent timeline is paused but the user is scrolling? 

So definitely avoid putting ScrollTriggers on nested animations. Instead, either keep those tweens independent (don't nest them in a timeline) -OR- just apply a single ScrollTrigger to the parent timeline itself to hook the entire animation as a whole to the scroll position.

 

Then you have this:

superTimeline.add(animateBackground(background, offset));
superTimeline.add(animateTags(tags, offset), 0);

function animateTags(tags, offset) {
  return gsap.to(tags, 2, { x: -offset, ease: "power4.easeOut" });
}

So you want to animate the tags using container animation but you are also animating the tags in the timeline you are using as the container animation and you are adding all the animations at zero seconds of said timeline. Again you are creating instances and animations in the timeline that should do just two things:

  1. Horizontally move a group of elements or a single element
  2. Serve as an indicator for the containerAnimation property to when create specific animations 

I created a super simple fork of your codepen so you can see how it actually is supposed to work:

See the Pen ExOrvWX by GreenSock (@GreenSock) on CodePen

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

  • 3 weeks later...

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...