RJWadley Posted November 11, 2022 Share Posted November 11, 2022 If you initialize ScrollSmoother after you create a tween or timeline with a ScrollTrigger, the tween doesn't work correctly. It will either get stuck at the beginning or snap to the end. Plus, if the page is not at the top when initialized, onEnter and onLeave are sometimes fired instantly. In React, effects in components higher in the tree are run later, and since ScrollSmoother is usually in one of the highest components it will always be initialized last, which causes this issue. See the Pen yLjQjBo by RJWadley (@RJWadley) on CodePen Link to comment Share on other sites More sharing options...
Rodrigo Posted November 11, 2022 Share Posted November 11, 2022 Hi, Right now I'm on my phone so I can't take a deep look into this. There are a couple of options you could try. One is to create a state property in the component where ScrollSmoother is being initialized. Una use effect hook with no dependencies toggle that state and pass it down to the child components in order to either conditionally render them or instantiate scrolltrigger in a use effect hook with that prop as a dependency. You could also wrap your app in a context provider and toggle some state in the context and listen to that in the components where the scrolltrigger instances are created and go the use effect route. Another option is to refresh the scrolltrigger instances after ScrollSmoother has been initialized. Happy Tweening! Link to comment Share on other sites More sharing options...
RJWadley Posted November 11, 2022 Author Share Posted November 11, 2022 Thanks for the reply, Rodrigo. Refreshing ScrollTrigger after the smoother is initialized does not fix the issue. This would be the preferred solution for me if it worked. Relying on some React state to recreate everything if the smoother changes seems like it would work until the underlying issue is fixed, although I don't anticipate that being very nice to performance. Something else I found that works is adding a reverse and a play to the enter trigger, although this will still break if the page isn't at the top when everything's initialized. onEnter: () => { console.log("onEnter TRIGGERED"); timeline.reverse(); timeline.play(); }, Link to comment Share on other sites More sharing options...
Rodrigo Posted November 11, 2022 Share Posted November 11, 2022 Hi regarding this statement: 3 hours ago, RJWadley said: Relying on some React state to recreate everything if the smoother changes seems like it would work until the underlying issue is fixed, although I don't anticipate that being very nice to performance. The idea of the state update is something that will change only once in the app's life-cycle, not a state property that will change regularly. There is a difference between one setup and another. ScrollSmoother doesn't change regularly, just once: const main = () => { const [smootherStarted, setSmootherStarted] = useState(false); useLayoutEffect(() => { const ctx = gsap.context(() => { ScrollSmoother.create({ smooth: 1, effects: true, }); setSmootherStarted(true); }); return () => ctx.revert(); }, []); return ( <main> <MyComponent init={smootherStarted} /> </main> ); }; export default main; Then: const MyComponent = ({ smootherStarted }) => { useLayoutEffect(() => { if (smootherStarted) { /* Create ScrollTrigger instances now */ /* This should happen only once */ } }, [smootherStarted]); return ( /* Content Here */ ); }; export default MyComponent; Also I don't know about performance issues in a case like this, I think the best way is to test, profile and see the behaviour of the app. Finally in your codepen example you have this: <div id="smooth-content"> <h1 class="title">Testing Ground</h1> <div class="filler"></div> <div class="anim"></div> <div class="filler"></div> <br /> </div> Keep in mind that you need an extra wrapper for ScrollSmoother to work properly: <div id="smooth-wrapper"> <div id="smooth-content"> <!--- ALL YOUR CONTENT HERE ---> </div> </div> Please take a good look at the documentation: https://greensock.com/docs/v3/Plugins/ScrollSmoother Happy Tweening! Link to comment Share on other sites More sharing options...
GreenSock Posted December 22, 2022 Share Posted December 22, 2022 GSAP 3.11.4 was just released and I added some code to ScrollSmoother to better handle this in an automatic way - even if ScrollTriggers exist BEFORE ScrollSmoother gets created, it should honor them now. 👍 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now