Jump to content
Search Community

ScrollTrigger: Hidden DIVs and consistent events

acg test
Moderator Tag

Recommended Posts

I'm working on something that is trying to use ScrollTrigger on what is effectively a "tabbed" interface. Each "tab" is a DIV that is shown/hidden according to some tab "buttons". However, I'm finding some challenges with the way ScrollTrigger triggers items within hidden DIVs. It seems as though ScrollTrigger fires the "onEnter" event (which I doesn't seem right) but then also doesn't trigger the actual GSAP animation (which seems weirdly inconsistent).

 

Notice in the included Pen that on startup, the DIV containing the second animation is "hidden". You can see that the start marker is up at the top of the screen. I don't know why it should necessarily be considered "started" since it isn't visible and therefore isn't really "above" or "below" the "start" point. If it is considered "above" the start point, it might make sense to trigger "onEnter", but then it doesn't actually run the animation (which seems weird). Notice that the console logs the "onEnter" event right at the start. Also notice that the timer which shows the hidden DIV after 3 seconds reveals that the blue block hasn't actually animated (note this example may only show the behavior if your browser leaves about 1/4 vertical screen space for the CodePen content area).

 

So, my questions are: What strategy is best to make ScrollTrigger ignore the hidden elements? And does it make sense to trigger "onEnter" but then not execute the GSAP animation itself?

See the Pen NWrrEXr?editors=1111 by acgresearch (@acgresearch) on CodePen

Link to comment
Share on other sites

Hey acg.

 

1 hour ago, acg said:

What strategy is best to make ScrollTrigger ignore the hidden elements?

ScrollTrigger looks at properties on the element itself to see if an element is hidden. In your case  the element itself doesn't have any properties applied directly to it to hide it - they are applied to a parent element. If you change the trigger for the second one to trigger: "#panel2" you'll see the ScrollTrigger is not created. So you can work around that by either changing the display of the box2, using the panel as the trigger, or not creating the ScrollTrigger until the elements are on the page (probably what you want to do).

 

1 hour ago, acg said:

does it make sense to trigger "onEnter" but then not execute the GSAP animation itself?

I'm not sure how I would answer that question directly, but I do think that firing the onEnter is the correct functionality. The default start value is 0 so the ScrollTrigger should fire immediately. And the onEnter should fire when the ScrollTrigger fires. Whether or not the animation should also be applied is a different question.

 

@GreenSock What do you think? I suppose we could check to see if an element has an .offsetParent before creating the ScrollTrigger.

@acg To be clear this wouldn't make your animation fire once it is displayed - you should still create the ScrollTrigger after it's added to the DOM.

Link to comment
Share on other sites

Can you actually confirm that this has been addressed in some way by the beta?

 

As you noted, you changed the code slightly. In your CodePen, the second call to "gsap.fromTo()" is using "#panel2" as the trigger instead of "#box2". When I change it back to "#box2", I believe it is behaving the same.

 

FWIW, I'm not convinced that "onEnter" is appropriate to be fired when the animation doesn't trigger. Another way to think of it. When the DIV is hidden, why should the "start" trigger be "at the top". Why not the bottom?

Link to comment
Share on other sites

On 10/21/2020 at 10:23 PM, acg said:

FWIW, I'm not convinced that "onEnter" is appropriate to be fired when the animation doesn't trigger. Another way to think of it. When the DIV is hidden, why should the "start" trigger be "at the top". Why not the bottom?

I actually don't see a problem here. Let me explain what's going on...

 

ScrollTrigger must figure out where the "trigger" is in the window, and it does that using getBoundingClientRect() but if you hide the trigger then the browser cannot accurately report the element's bounds. That's why the markers are where they are. And consequently, it reaches the end IMMEDIATELY because the "end" is at a scroll position of 0. You've got your toggleActions set to "pause" when it hits the end, so the animation never actually gets to go anywhere because it gets paused right away. 

 

See why? 

 

As far as I can tell, it's working perfectly. 

 

If you want ScrollTrigger to accurately map where your .panel2 element is, you can use a "refreshInit" event listener to toggle display to true just for during the refresh, and then revert it after the refresh. In fact, to make it easier, you can return a set() in the event handler and ScrollTrigger will automatically revert that set for you after the refresh:

ScrollTrigger.addEventListener("refreshInit", () => gsap.set(".panel", {display:"block"}));

Does that resolve things for you? 

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