Jump to content
Search Community

Mimicing Affix with Gsap

JohnMersal test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hello amazing community!

 

I'm a big GSAP fan and this is my first time posting on this forum.

 

I'm working on a newsletter project that has a layout that you can find on my CodePen. 

I'm trying to achieve "Bootstrap - Affix" similar behavior on my template ,where affix wont work for me, using GSAP.

 

--- Functionality needed:

I need to hide the sidebar whenever the bottom of the sidebar hits the top of the "Separator area, which is the AD", and shows back once the next section is on top of the page. 

 

As you can see on the CodePen while trying to scroll from top to bottom in a single go and go back up in a single go, you can see everything working just fine without any glitches and it is all buttery smooth.

However, once you reach back to the top, everything breaks and the sidebar stops hiding (while it sometimes hides and this happens VERY randomly).

 

I tried messing around with the toggleActions but I was unsuccessful (maybe I don't understand them well, but I couldn't get it to work).

 

Any guidance in the correct direction would be greatly appreciated.

Thank you 

John

See the Pen KKeYYRX by john-mersal (@john-mersal) on CodePen

Link to comment
Share on other sites

  • Solution

Congratulations on your first post, @JohnMersal! Sorry about the delayed response. Normally we're pretty quick around here. 

 

I think the main problem with your first approach was this: 

toggleActionsStds = "restart resume resume reverse"

I think you meant to do this:

toggleActionsStds = "restart play play reverse"

Remember that resume will honor the playhead direction, so if the timeline was previously reversed, then calling resume() will just continue in the backward direction. 

 

There may be other logic issues with the way you set things up, but I don't have a lot of time to dissect it at the moment. 

 

By the way, if you're just gonna have one animation in your timeline, you don't even need to create a timeline. I mean it's fine if you do, but you could shorten your code: 

// long
let tl = gsap.timeline({ scrollTrigger: {...} });
tl.to(...);

// short
gsap.to(... { scrollTrigger: {...} });

And if you're not adding any animations and you're only creating a timeline in order to put a pinning ScrollTrigger, you can just use ScrollTrigger.create(): 

// long
let tl = gsap.timeline({ scrollTrigger: {...} });
                        
// short
ScrollTrigger.create({...});

I hope that helps! And good job coming up with a solution on your own. 🙌

 

Glad you're out of "lurker mode" now. 👍

Link to comment
Share on other sites

Hello @GreenSock, Thank you so much for your response, and I can understand the delay with the huge amounts of posts and help you guys are doing here!

 

1 hour ago, GreenSock said:

I think you meant to do this:

toggleActionsStds = "restart play play reverse"

Remember that resume will honor the playhead direction, so if the timeline was previously reversed, then calling resume() will just continue in the backward direction. 

That worked like a charm! I did not know the difference between play and resume!

I assumed as much that is why my other solution with "onEnter and onLeave" worked with the same logic.

 

I just have a small follow up question regarding your suggestions to shorten the code. 

I'm not familiar with the one animation timeline syntax, first of all is there documentation for that? As I've failed to find it.

This is my attempt but obviously it didn't really work.

 

ads.forEach(
        function (ad, idx, array) {
            gsap.to(sideBar, 
                    {opacity:0},
                    { scrollTrigger: {
                      trigger: ad,
                      start: `0 ${sideBar.clientHeight + 40}`,
                      end: `1% ${sideBar.clientHeight + 40} `,
                      toggleActions: toggleActionsStds,
                      ease: easingSetting,
                      duration:0.05
                    } 
            });
        }
    );

Let me know what I did wrong here. Thank you!

Link to comment
Share on other sites

Hey,

 

you can find the approach here, at the simple example

gsap.to(".box", {
  scrollTrigger: ".box", // start the animation when ".box" enters the viewport (once)
  x: 500
});

 

ScrollTrigger has no "ease" or "duration" property, so the default values of your timeline must be included in the to() method.

  ads.forEach(function (ad, idx, array) {
    gsap.to(sideBar, {
      opacity: 0,
      ease: easingSetting,
      duration: 0.05,
      scrollTrigger: {
        trigger: ad,
        start: `0 ${sideBar.clientHeight + 40}`,
        end: `1% ${sideBar.clientHeight + 40} `,
        toggleActions: toggleActionsStds
      }
    });
  });

Take a look at the first video in the documentation I linked you above, it also uses this kind of syntax. But there are also other examples in the demos.

 

And the other would look something like this:

 ScrollTrigger.create({
    trigger: sideBar,
      pin: true,
      markers: true,
      scrub: false,
      start: "top 20px",
      end: `${wrapper.clientHeight - 40} ${sideBar.clientHeight + 20}`,
      toggleActions: toggleActionsStds
  });

 

Hope this helps.

  • Like 3
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...