Loust Posted January 31 Share Posted January 31 Hello community. So, after numerous searches and head-banging, I can't find the solution. I have an animation triggered by ScrollTrigger. This animation targets phrases. These phrases are inserted into the DOM through a map, triggered either on rendering or when the state changes. The desired effect is that the state, which is an array of strings, changes when the user hovers over one of the icons next to these phrases. Depending on the targeted icon, there can be two, three, or four phrases. The problem is that during onLeave, onEnterBack, or onLeaveBack, only the number of phrases from the first targeted icon is animated. In short, the initial state contains four phrases; if I then hover over an icon containing 3 phrases, then another icon with 2, then one with 3, then one with 4, only 3 phrases are animated in the ScrollTrigger animation. If the sequence is 4 phrases initially, then 2 on hovering over an icon, then 3, then 4, only 2 phrases are animated. I specify that I also use Locomotive Scroll, and due to the ScrollTrigger proxy, I cannot use useEffect with a dependency array in my .js function. Link to comment Share on other sites More sharing options...
GSAP Helper Posted January 31 Share Posted January 31 Without a minimal demo, it's very difficult to troubleshoot; the issue could be caused by CSS, markup, a third party library, a 3rd party script, etc. Would you please provide a very simple CodePen or Stackblitz that illustrates the issue? Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. See if you can recreate the issue with as few dependancies as possible. Start minimal and then incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, at least we have a reduced test case which greatly increases your chances of getting a relevant answer. See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo: Using a framework/library like React, Vue, Next, etc.? CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import the gsap-trial NPM package for using any of the bonus plugins: React (please read this article!) Next Svelte Sveltekit Vue Nuxt Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. ✅ Link to comment Share on other sites More sharing options...
Rodrigo Posted January 31 Share Posted January 31 Hi, Based on your description ScrollTrigger Batch seems to be the right tool for this scenario: https://gsap.com/docs/v3/Plugins/ScrollTrigger/static.batch() Also proper cleanup is very important with frameworks, but especially with React. React 18 runs in strict mode locally by default which causes your useEffect() and useLayoutEffect() to get called TWICE. Since GSAP 3.12, we have the useGSAP() hook (the NPM package is here) that simplifies creating and cleaning up animations in React (including Next, Remix, etc). It's a drop-in replacement for useEffect()/useLayoutEffect(). All the GSAP-related objects (animations, ScrollTriggers, etc.) created while the function executes get collected and then reverted when the hook gets torn down. Here is how it works: const container = useRef(); // the root level element of your component (for scoping selector text which is optional) useGSAP(() => { // gsap code here... }, { dependencies: [endX], scope: container }); // config object offers maximum flexibility Or if you prefer, you can use the same method signature as useEffect(): useGSAP(() => { // gsap code here... }, [endX]); // simple dependency Array setup like useEffect() This pattern follows React's best practices. We strongly recommend reading the React guide we've put together at https://gsap.com/resources/React/ If you still need help, here's a React starter template that you can fork to create a minimal demo illustrating whatever issue you're running into. Post a link to your fork back here and we'd be happy to take a peek and answer any GSAP-related questions you have. Just use simple colored <div> elements in your demo; no need to recreate your whole project with client artwork, etc. The simpler the better. Happy Tweening! Link to comment Share on other sites More sharing options...
Loust Posted February 1 Author Share Posted February 1 Thank you for your responses and their speed. So, yes, I had previously tested useGSAP without success. I was completely unfamiliar with Batch, it's really good, but it creates a very erratic behavior after the state change. Currently, I'm trying to create a minimal demo with React, but as soon as I try to go to CodePen, it asks me to log in, and I'm not sure where I put my password. I'm waiting to have it sent to me, otherwise I'll quickly create another account. Link to comment Share on other sites More sharing options...
Rodrigo Posted February 1 Share Posted February 1 Hi, For frameworks like react better use stackblitz, here is a link for a starter dem that you can fork https://stackblitz.com/edit/react-cxv92j Happy Tweening! Link to comment Share on other sites More sharing options...
Loust Posted February 1 Author Share Posted February 1 https://stackblitz.com/edit/stackblitz-starters-ywnimj?description=React TypeScript starter project&file=src%2FApp.tsx,src%2Fstyle.css&title=React Starter This kind of behavior roughly illustrates the problems I often encounter. Link to comment Share on other sites More sharing options...
Loust Posted February 1 Author Share Posted February 1 In fact, the scrollTrigger works very well. However, once I hover over one of the buttons, only their sentences are taken into account from a set of potentially larger number of sentences. Link to comment Share on other sites More sharing options...
Solution GreenSock Posted February 1 Solution Share Posted February 1 I noticed several issues: You're not doing proper cleanup. Every time you change the text, you're creating an entirely new animation and ScrollTrigger, and all the old ones are sticking around. So you end up with more and more and more that are all trying to operate on the same elements. It looks like you're using a setTimeout() to work around the fact that React doesn't immediately apply the changes when you setText(). If you're trying to run an animation when that text changes, you should do it the proper way in React which is to set up an effect with that text as a dependency (this is totally unrelated to GSAP, FYI). You appear to be hard-coding onEnter/EnterBack/onLeaveBack callbacks on your ScrollTrigger to do exactly what you can do more easily with toggleActions. // old onLeave: () => tl.reverse(), onEnterBack: () => tl.play(), onLeaveBack: () => tl.reverse() // new toggleActions: "none reverse play reverse" There seem to be logic issues - I don't really understand what you're expecting to happen. Here's my best guess at what you're trying to do: https://stackblitz.com/edit/stackblitz-starters-8ab6xd?description=React TypeScript starter project&file=src%2FApp.tsx&title=React Starter 1 Link to comment Share on other sites More sharing options...
Loust Posted February 1 Author Share Posted February 1 Indeed, I didn't think of that approach. I searched for many things, yet in vain. Thanks for your help. One question; so now, we prefer to use toggleActions? Are onEnter, onEnterBack, etc., deprecated? I'm new to the game, actually. I've been using GSAP for about a week, and React for a few months. Otherwise, I'll look on the internet to find out about toggleAction. Thanks again, anyway ;), your solution is very clean. Link to comment Share on other sites More sharing options...
GreenSock Posted February 1 Share Posted February 1 25 minutes ago, Loust said: One question; so now, we prefer to use toggleActions? Are onEnter, onEnterBack, etc., deprecated? No, not at all. We made ScrollTrigger to be super flexible. toggleActions aren't new at all - they were in the original release. onEnter/onLeave/onEnterBack/onLeaveBack are simply callbacks that allow you to do ANYTHING at those points. The toggleActions are just a shortcut way to control the associated animation. Have fun! Link to comment Share on other sites More sharing options...
Loust Posted February 1 Author Share Posted February 1 I understand completely. `onEnter/onLeave/onEnterBack/onLeaveBack` allows associating functions that are not necessarily correlated with the triggering animation. A brilliant approach. Truly impeccable what you've done. I wholeheartedly recommend. Thanks once again to you and your responsive community space. One last question, if I may, don't bother otherwise, I'll do my research and tests, but does `ScrollTrigger.create()` auto-destruct like itself, kind of one-time use? Link to comment Share on other sites More sharing options...
Cassie Posted February 1 Share Posted February 1 This is a lovely video explaining toggleActions from @Carl 3 Link to comment Share on other sites More sharing options...
GreenSock Posted February 1 Share Posted February 1 6 minutes ago, Loust said: One last question, if I may, don't bother otherwise, I'll do my research and tests, but does `ScrollTrigger.create()` auto-destruct like itself, kind of one-time use? I don't understand the question. When/How would you expect it to "auto-destruct"? Maybe it would help if you explain the "why" behind your question. Perhaps you were asking if ScrollTriggers created while the useGSAP() function executes will automatically revert and destroy themselves when the hook gets torn down? If so, the answer is "yes". 🙂 8 minutes ago, Loust said: A brilliant approach. Truly impeccable what you've done. I wholeheartedly recommend. Thanks once again to you and your responsive community space. 💚 Link to comment Share on other sites More sharing options...
Loust Posted February 2 Author Share Posted February 2 2 hours ago, GreenSock said: Je ne comprends pas la question. Quand/Comment vous attendez-vous à ce qu'il « s'autodétruise » ? Il serait peut-être utile que vous expliquiez le « pourquoi » derrière votre question. Peut-être demandiez-vous si les ScrollTriggers créés pendant l' exécution de la fonction useGSAP() reviendraient automatiquement et se détruiraient lorsque le hook serait détruit ? Si tel est le cas, la réponse est « oui ». 🙂 Yes, that's exactly what I was referring to, to avoid memory leaks and the kind of behavior I encountered with my bad practice using a simple ScrollTrigger. Thanks, Cassie, for your video; I'll watch it tomorrow. 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