Jump to content
Search Community

ScrollTriggers firing too early -- change between 3.12.7 and 3.13.0

gmullinix

Recommended Posts

Posted

I have a training module set up with multiple pages of content (all contained in one html file). I use a timeline to hide/show each page. Each page has a Scrolltrigger set up to fire when the bottom of the page hits the bottom of the viewport (called the "scrollEnd" Scrolltrigger). In my demo there's also some Scrolltriggers to animate text. All ST's are disabled upon creation and then re-enabled when their associated page is visible.

 

This approach works as expected when using GSAP 3.12.7.

CodePen: 

 

However, things break when using GSAP 3.13.0.

edit: removed Codepen URL because I forgot to fork it before fixing the code

 

Things that are breaking:

--animations don't work correctly, they fire too early/all at once

--on short pages, the scrollEnd "onEnter" method fires immediately upon creation, before the page is visible

 

 

I hope the demos are reduced enough, I know it's still a lot of code to wade through. 😩

 

Any idea what might have changed between versions, and how can I get this functionality working again?

See the Pen yyNmdNJ by gem0303 (@gem0303) on CodePen.

Posted

Hi,

 

Sorry but there is far too much code in your demo to follow and try to figure out what you're trying to achieve.

 

It seems though that using the clamp() feature seems to help:

https://gsap.com/docs/v3/Plugins/ScrollTrigger/#start

 

var tween = gsap.from(el, {
  scrollTrigger: {
    trigger: el,
    start: "clamp(center center)",
    markers: true,
  },
  opacity: 0,
  duration: 1
});

 

That seems to make it work the way you intend.

 

Hopefully this helps

Happy Tweening!

Posted

Yeah, it looks to me like the 3.13.0 actually FIXES a bug. Previously, if you created a ScrollTrigger whose start position was already passed, it didn't immediately fire the onEnter() until the 2nd refresh(), but now it properly calls it on the first refresh().  

 

In your demo, you set the #page_2 start: "bottom bottom+=5px" but that element is the same height as the viewport, thus its bottom would already be 5px beyond the start trigger. Therefore, the onEnter() should indeed fire. That's also why Rodrigo's suggestion to use clamp() fixes it too - it won't allow the start to be a negative value.  

 

Does that clear things up? 

 

If you still think something is broken in ScrollTrigger, please provide a minimal demo that more clearly isolates a single issue and we'd be happy to take a peek. 

Posted

Thank you both for the replies. It appears that disabling/enabling Scrolltriggers in 3.12.7 combined with the onEnter bug actually hit a sweet spot for my particular project so ScrollTriggers only fired when their content was visible. I'm trying to recreate this in 3.13.0 but my setup with absolutely positioned pages set to display: none is making them fire prematurely. I don't think it's a bug in ScrollTrigger, but I'm having trouble finding a workaround.

 

It appears that clamp() does fix my issue, but has the undesired side effect of having to scroll on each page before any content appears. While I can see this being ideal for scrubbed animations, it makes my pages look empty on load and won't be an acceptable solution. (Side question -- does ST support a way to only use endClamp, not startClamp?)

 

Since my ScrollTriggers are initialized while the parent page is display: none, the start values always return as 0 and thus fire instantly. I tried to write a custom function that gives a fake start value so the ST doesn't fire (then later when parent is visible I call ST.refresh() and it updates to correct start value).

 

if (parent == hidden) {
   return "top 100000px"
}

 

However ScrollTrigger appears to overwrite my fake value and the ST fires anyway. Is there something else I can try? Or is there any way to create a ScrollTrigger but have it disabled by default? I know one suggestion is to wait to create the ScrollTriggers until the parent page is visible, but hoping to avoid that route for a few reasons (can go into detail if helpful).

 

Simplified Codepen: 

See the Pen MYwNMEo by gem0303 (@gem0303) on CodePen.

 

Thank you for your time!

Posted
29 minutes ago, gmullinix said:

Side question -- does ST support a way to only use endClamp, not startClamp?

Sure. Just wrap "clamp(...)" around your end but not your start. Or did I misunderstand your question? 

 

30 minutes ago, gmullinix said:

if (parent == hidden) {
   return "top 100000px"
}

 

However ScrollTrigger appears to overwrite my fake value and the ST fires anyway.

I didn't see this in your minimal demo - am I missing it? I assume you could do a function-based value like: 

start: () => parent === hidden ? 99999 : "bottom bottom+=5px",

And then just make sure you refresh() to trigger that to re-calculate when the page becomes visible.

 

If you're still struggling, it'd be super helpful if you provided a very, very minimal demo that only isolates the problem you're struggling with (one at a time). 🙂

Posted
18 hours ago, GreenSock said:

Sure. Just wrap "clamp(...)" around your end but not your start. Or did I misunderstand your question? 

Misunderstood, but it's my fault for not explaining my question clearly. I meant is there a way to apply clamp only to elements at the bottom of the page, not the top? Meaning negative start values are fine, but start values beyond the bottom of the page are clamped.

 

(Also, funny enough, it looks like you added the ability to clamp at the end of a page because of my forum post back in 2023, so it stands to reason I'm back here bugging you about it again. 😅)

 

18 hours ago, GreenSock said:

I didn't see this in your minimal demo - am I missing it?

 

You weren't missing it; it was not in the demo because I was rushing to post before logging off for the day. However, it's in there now and working! My mistake was using a start value of "top 10000px" -- GSAP didn't like this. Switching to a simple number like you suggested works perfectly.

 

After more tinkering, I reached a solution I'm very happy with! I updated the Codepen linked in my last post to simplify things further and show the custom start function (calcStart) I'm using.

 

Thanks again for the support!

 

Codepen Link:

See the Pen MYwNMEo by gem0303 (@gem0303) on CodePen.

Posted
28 minutes ago, gmullinix said:

Meaning negative start values are fine, but start values beyond the bottom of the page are clamped.

That actually doesn't matter since ScrollTrigger will only clamp negative start values not positive ones, so any start point that is below the start point of the trigger will not be clamped.

 

Great to hear that you were able to sort it out though.

 

Hopefully this clear things up

Happy Tweening!

Posted

I don't think I'm doing a good job explaining what I'm looking for with clamp. Hopefully the attached Codepen helps (please open in its own window). I'm basically requesting a new feature, something like start: "endClamp(top center)"

 

What this would do:

  • Ensures all elements on the page animate, even if their start positions are too far down to trigger normally
  • But elements at the top of the page would be visible without having to scroll

See the Pen KwdzVJw by gem0303 (@gem0303) on CodePen.

Posted

Ah, I think you could achieve that using the existing API, although we haven't documented .setPositions() on purpose - we weren't sure it'd be useful for end users like yourself: 

 

See the Pen WbQwwBp?editors=0010 by GreenSock (@GreenSock) on CodePen.

 

Is that what you're trying to do? 

  • Like 1

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