Jump to content
Search Community

Scrolltrigger on body with scrub, but start and end are based on different elements?

Trynix test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi everyone,

 

I have a sticky menu that has some animation changes based on its current position on page. I'm tracking scroll progression on page by applying scrolltrigger on "body" and having scrub enabled (need scrub as the animation is progressive rather than in steps).

Is it possible to have the "start" and "end" settings of the scroll trigger apply based on elements other than body, or is my only recourse is to have a parent container that starts with the sticky nav and ends at the desired scrolltrigger end location?
 

Here's an example of what I'm referring to: 

In this example, intent is for start to occur at ".start-div" and end to occur at ".end-div".

 

Note that I can't use static values for start and end because the page size increases in size on mobile due to many 2 column grids on page becoming 1 column grids on narrower devices.

See the Pen podNNdy by mazayadigital (@mazayadigital) on CodePen

Link to comment
Share on other sites

Thank you very much!! That's pretty much it :)

 

Following up on a couple of steps I have:

 

- I'd like the animation to not repeat or reverse if scroll-end is reached (but to repeat/reverse if a person scrolls up and down without reaching scroll-end). I tried setting "once" to true as you'll see in example below, but for some reason if I scroll quickly to the bottom, the progress bar gets stuck to where it was at the instant I cross scroll-end, not taking into account the scrub delay duration. Is there an alternative approach?

See the Pen oNoYZMZ by mazayadigital (@mazayadigital) on CodePen

 

- If I'd like to play another animation only if scroll-end is reached, would onLeave by the best option for this?
 

Thank you once again!

Link to comment
Share on other sites

That has already been fixed in the next release which you can preview at https://assets.codepen.io/16327/ScrollTrigger.min.js

 

In the meantime, you can just use an onLeave and add an onComplete to the scrub tween that kills the ScrollTrigger: 

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

 

Don't forget that you can add fastScrollEnd: true if you'd like. 

 

16 minutes ago, Trynix said:

- If I'd like to play another animation only if scroll-end is reached, would onLeave by the best option for this?

Yep, sounds reasonable. 

  • Like 1
Link to comment
Share on other sites

3 hours ago, GreenSock said:

That has already been fixed in the next release which you can preview at https://assets.codepen.io/16327/ScrollTrigger.min.js

 

In the meantime, you can just use an onLeave and add an onComplete to the scrub tween that kills the ScrollTrigger: 

 

 

 

Don't forget that you can add fastScrollEnd: true if you'd like. 

 

Yep, sounds reasonable. 

Hi again,

 

I've implemented an animation based on the solution above, can be seen on this site: https://raisegiving-6e5a4b.webflow.io/ . It's the funding progress bar.

 

The weird issue I'm facing is that it works flawlessly on desktop. On mobile it works ok but sometimes it suddenly reverses to 0 (either after a scroll down or a scroll up). It happens on both firefox and chrome on android. any idea what could be causing this please??

 

The way I implemented it is that I declared an object (progressVal = {var:0}) and use gsap to update the value of progressVal.var between 0 and 1 depending on scroll status, and onUpdate it calls a function. That function uses the value of Var to update the funding progress.

Link to comment
Share on other sites

5 hours ago, Trynix said:

The weird issue I'm facing is that it works flawlessly on desktop. On mobile it works ok but sometimes it suddenly reverses to 0 (either after a scroll down

It’s very difficult to troubleshoot a live site - it’s not something we offer here but my guess is that this is related to the fact that some mobile browsers CHANGE the size of the viewport when you scroll because they show/hide the browser address bar, thus that causes a ScrollTrigger.refresh() which updates the start/end values accordingly. Some options I see:

  1. Prevent the window from resizing in that case - there’s a helper function in the docs that shows how: https://greensock.com/docs/v3/HelperFunctions#scrollResize
  2. Add some logic on resize to calculate where the new scroll position should be in order to match the progress of your animation (this probably isn’t super simple)
  3. If you still need help, please create a minimal demo in CodePen and post it here. I’m sure you’d need to test it in CodePen’s “debug” view so that the window resizes when the browser address bar shows/hides because it won’t do that in an iframe like CodePen’s edit mode uses. Please keep your demo to the absolute minimum possible to reproduce the issue (no need to put your whole page in there). 
Link to comment
Share on other sites

6 hours ago, GreenSock said:

It’s very difficult to troubleshoot a live site - it’s not something we offer here but my guess is that this is related to the fact that some mobile browsers CHANGE the size of the viewport when you scroll because they show/hide the browser address bar, thus that causes a ScrollTrigger.refresh() which updates the start/end values accordingly. Some options I see:

  1. Prevent the window from resizing in that case - there’s a helper function in the docs that shows how: https://greensock.com/docs/v3/HelperFunctions#scrollResize
  2. Add some logic on resize to calculate where the new scroll position should be in order to match the progress of your animation (this probably isn’t super simple)
  3. If you still need help, please create a minimal demo in CodePen and post it here. I’m sure you’d need to test it in CodePen’s “debug” view so that the window resizes when the browser address bar shows/hides because it won’t do that in an iframe like CodePen’s edit mode uses. Please keep your demo to the absolute minimum possible to reproduce the issue (no need to put your whole page in there). 

Thanks for your feedback, I tried to replicate the necessary elements of my page to the attached codepen, and indeed the issue re-occurs when browsing view mobile and with debug view active.

 

From what I see, it seems that the start location updates to the current start-div position at different points, and because the start-div element is sticky, it ends up updating to way below where the original start position was.

 

I'm not sure what's the cause of these random updates, but I guess a way around it is to attach the start position on a static element instead of a sticky one.

 

See the Pen WNXoKxo by mazayadigital (@mazayadigital) on CodePen

Link to comment
Share on other sites

Ah, that makes perfect sense - if you're setting something to position: sticky just think about what happens when a ScrollTrigger.refresh() occurs - ScrollTrigger has to revert all of its changes to their original state and then one-by-one from top-to-bottom, it calculates the start/end positions of things. So imagine where your position: sticky element is when the page FIRST loads (scroll position of 0) - let's just say it's 500px down from the top. Fine. It's measured accordingly. But then if you scroll way PAST it (and it became "sticky" outside of ScrollTrigger's control since it's not "pinned"), it may now be 2000px down from the top of page at that point, throwing off all the measurements. 

 

The moral of the story: don't use a trigger element that's being shifted around like that outside of ScrollTrigger's control. 

 

Does that clear things up? 

Link to comment
Share on other sites

47 minutes ago, GreenSock said:

Ah, that makes perfect sense - if you're setting something to position: sticky just think about what happens when a ScrollTrigger.refresh() occurs - ScrollTrigger has to revert all of its changes to their original state and then one-by-one from top-to-bottom, it calculates the start/end positions of things. So imagine where your position: sticky element is when the page FIRST loads (scroll position of 0) - let's just say it's 500px down from the top. Fine. It's measured accordingly. But then if you scroll way PAST it (and it became "sticky" outside of ScrollTrigger's control since it's not "pinned"), it may now be 2000px down from the top of page at that point, throwing off all the measurements. 

 

The moral of the story: don't use a trigger element that's being shifted around like that outside of ScrollTrigger's control. 

 

Does that clear things up? 

It does, thank you very much :) I've made the update and it works flawlessly now!!

 

I'm trying a different approach highlighted in the attached example. 

See the Pen OJObqxN by mazayadigital (@mazayadigital) on CodePen

 

Basically I want to animate the target element every time it passes "action-div", and reverse that animation every time it goes back across it. I've put the animation as increase in width by 20% as an example but it'll be more sophisticated. I've added ".action-div" as the scrolltrigger target but it seems to only target the first element it comes across. Is there a way to have it target all ".action-div" instances for the trigger action?

Thanks!

Link to comment
Share on other sites

The way you've set that up wouldn't logically make much sense - you've got ONE animation that's going to width: 20%...but you want it to get triggered every time it hits any of the action-div elements? So let's say it hits the first one and animates to width: 20% as you indicated. Now what? Once it passes the second one, it fires that tween and animates from 20% to...20%? (no change) See the issue? 

 

And it wouldn't make sense if one ScrollTrigger could have a bunch of triggers. Remember, the whole concept relies on blocking out a certain scroll area where there's a start and an end. So how could it have a bunch of starts and ends? How would it report its overall progress at any given time? If there's a scrub on it, how would that even behave? 

 

There are many ways to approach this. Here's one (with an alternate solution commented-out): 

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

 

Notice I'm animating scaleX instead of width because that's easier on the browser rendering-wise. 

 

Is that what you're looking for? 

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