Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Jack7cz

ScrollTrigger does not recalculate start/end values when content changes its height

Go to solution Solved by akapowl,

Recommended Posts

Hi guys, I am trying to reproduce Midnight.js (https://aerolab.github.io/midnight.js/) with ScrollTrigger. And I've encountered problem. When some content on page changes its height, ScrollTrigger does not recalculate start/end values as it does when resizing window.

 

I was wondering if ScrollTrigger can recalculate it on its own, or my backup idea is to use ResizeObserver maybe?

 

Here is my pen:

 

Every help will be much appreciated.

 

Thanks.

See the Pen NWyGbZw by jack7cz (@jack7cz) on CodePen

Link to comment
Share on other sites

Hi @PointC,

thank you for your message :).

 

Do you mean to use refresh method in combination with ResizeObserver, right? Or is there another way?

 

I replicated in another Codepen what I have in my Vue project with ResizeObserver. Actually I did use .refresh() method already. Unfortunately in the Codepen the recalculation is not working at all :O. Any idea why? I would like to show the problem in there.

 

See the Pen abqvpVO by jack7cz (@jack7cz) on CodePen

 

But in my project where the recalculation somehow works, I am running into issues in case when the header is half in inverted (dark) section and half in normal (white) section.

 

.refresh()

When I click on something which changes height of page .refresh(), then probably "from" settings are used from my fromTo Tweens as the whole dark height is shown and to have the header correctly half dark/ half white. User needs to scroll a little. I've tried to force to move the scroll position programmatically, but the effect is that the whole dark header still blinks.

 

Killing all tweens

I did also try to kill all tweens and set them again, which I believe is nonsense to do, but then it applied my timeline.set( settings instead of "from" settings from "fromTo". Just saying what I've tried.

 

Thanks a lot

 

Link to comment
Share on other sites

I don't think you want to call refresh on resize as ScrollTrigger will do that automatically. I was referring to a manual change in the height of an element via click or some other interaction. Or maybe you add elements to the DOM. In those cases, you'd want to call refresh. 

 

I'm not quite following your demo and what is supposed to be happening so I made a quick example for you. Here are just a few divs, a spinning target div triggered by ScrollTrigger and an expanding content area. Notice how the tween that expands/closes the content box calls refresh when the tween completes? See how the markers change each time that happens? That's generally when you want to manually call refresh - when something has changed in the DOM to cause a reflow. 

 

See the Pen JjpYwBO by PointC (@PointC) on CodePen

 

Hopefully that makes sense.

 

Happy tweening.

:)

  • Like 3
Link to comment
Share on other sites

I think I see your point. In your demo, you are using scrollRefresh in click listener for one specific situation. But I wanted to use me code all over the website, so I don't want to add ScrollTrigger.refresh() on every button that shows some content or so. There can be more situations when the document height changes. That's why I used ResizeObserver, which checks if there are some changes in the size (height) of document. So I guess this is the only possible way.

 

I've updated my Codepen, now the ResizeObserver is working correctly.

See the Pen abqvpVO by jack7cz (@jack7cz) on CodePen

 

Would you know if there is something I can do with the problem, when header is on the border of two sections (image 1)? When the button is clicked, which at the end fires ScrollTrigger.refresh(), then the whole dark header is shown (image 2) instead of half white / half dark header which is seen on image 1? 

 

291317420_Snimekobrazovky2022-05-06v18_19_45.thumb.png.03c39fa20434775de72d4cb23c80c377.png

 

1019641911_Snimekobrazovky2022-05-06v18_19_54.thumb.png.ab250fb9ae2d87e0e6064c1817d84e3e.png

 

Thank you very much for you help :).

 

 

Link to comment
Share on other sites

If you're not animating the element to a new height, ResizeObserver should work just fine. I was just referring to your first demo that was firing constantly on window resize and then calling refresh multiple times. Probably not what you want. But yeah, seems like it's working fine with what you have now - so go for it. :)

 

24 minutes ago, Jack7cz said:

Would you know if there is something I can do with the problem, when header is on the border of two sections (image 1)?

Sorry, I'm just not following the question. Maybe you could reduce the demo a bit to something super simple.

  • Like 1
Link to comment
Share on other sites

Hi @PointC,

thank you for your message :).

 

I've tried to reduce it little bit and I've added also comments into my code so it is hopefully more understandable. As you can see on the video below, when the header is half white, half dark and you click the button, then the header becomes fully dark, which is not something I wanna to happen. It should stay half white and half dark as before the button was clicked. I am wondering if this is something that could be fixed :).

 

See the Pen abqdGWm by jack7cz (@jack7cz) on CodePen

 

 

Thank you,

Jakub

 

 

Link to comment
Share on other sites

  • Solution

Hello @Jack7cz

 

There are a couple of things off with your code - the most impactful of them being, that you are nesting ScrollTriggers in individual tweens of a timeline. That is not valid and actually one of the most common ScrollTrigger mistakes, as you can read more on in this article:

 

 

 

 

That is the main reason why you are having that issue you mentioned on refresh. So you will definitely need to refactor your code with that regard.

 

And here are some additional notes:

  • I think the immediateRender: true should rather be inside the to-part of a fromTo-tween and not in the from-part
     
  • If you are using the invalidateOnRefresh: true because at some point the height of your nav might be changing and thus the calculations for the clipPath-tweens need to be done from scratch, make sure to also use function-based values - otherwise the invalidateOnRefresh will not have much of an effect
     
  • When tweening on clipPaths make sure to always include the units - even and especially when the value is 0 - so in your case 0px instead of 0 e.g., to avoid any possible misinterpretations by GSAP

 

 

I'm not 100% sure if I caught everything in there or if there might be an easier or more concise way to do it but here is a working fork of your demo.

 

I hope that'll help a bit - happy tweening!

 

EDIT:

I just now noticed there still being a problem when you first scroll past the button and enter the 'navbar-from-white1' ScrollTrigger, then back up to the button and the nav becoming black again and then click the button to change the height of the red box - the nav will turn white on click.

 

But I'm running out of time now, so if anyone sees something obviously wrong in my codepen or has an idea what that might be realated to in the first place, please chip in.

 

See the Pen KKQVBNo by akapowl (@akapowl) on CodePen

 

 

 

EDIT 2:

I've had some more time to tinker with it - and it appears that not setting immediateRender to false and setting the 'initial state of the headers' after the creation of the ScrollTriggers (instead of doing it beforehand) does seem to resolve that issue mentioned above. Since my brain is in sunday mode, I couldn't say I really get around why exactly that is the case though 😅

 

See the Pen gOvPBQp by akapowl (@akapowl) on CodePen

  • Like 5
Link to comment
Share on other sites

Hi @akapowl ,

you are real superhero :D! Now everything works fine, I was even able to solve other problems I had with this in my SPA app (for example handling the header when going back or forward in history).

 

Thank you very much, now is even more clear to me the problem about nesting timelines with ScrollTrigger :).

 

Have a nice day,

Jakub

  • Like 2
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.
×