Share Posted July 17, 2020 Hello, I hope you all are doing well. I am becoming a little more familiar with GSAP and read about the gsap.utils.toArray which would be useful for animating multiple items and I was wondering how I would use this in React. I gave it shot trying to make it work, but for me it only worked on one element. I also had trouble setting up this on codepen. I originally had const st = useRef(ScrollTrigger.defaults({toggleActions: "restart reset restart reset"})); but on Codepen it says ScrollTrigger.defaults is not a function. The rest of the code are identical to what I wrote. I am using this codepen as a reference: See the Pen yLeNodj by GreenSock (@GreenSock) on CodePen I would really appreciate on any advice on how to approach this! (This one below is mine) See the Pen RwrBKVM?editors=0010 by FarhanSU (@FarhanSU) on CodePen Link to comment Share on other sites More sharing options...
Share Posted July 17, 2020 You're loading the wrong ScrollTrigger - the one you loaded is from a completely different library. BAD: https://cdnjs.cloudflare.com/ajax/libs/ScrollTrigger/1.0.4/ScrollTrigger.min.js GOOD: https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.1/ScrollTrigger.min.js 1 Link to comment Share on other sites More sharing options...
Author Share Posted July 17, 2020 18 hours ago, GreenSock said: You're loading the wrong ScrollTrigger - the one you loaded is from a completely different library. BAD: https://cdnjs.cloudflare.com/ajax/libs/ScrollTrigger/1.0.4/ScrollTrigger.min.js GOOD: https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.1/ScrollTrigger.min.js I am sorry again! This is the link to a working one: https://codesandbox.io/s/suspicious-leaf-up3l7?file=/src/App.js Link to comment Share on other sites More sharing options...
Share Posted July 18, 2020 13 hours ago, FarhanSU said: This is the link to a working one: https://codesandbox.io/s/suspicious-leaf-up3l7?file=/src/App.js It's not working - it still has a lot of errors for me. Link to comment Share on other sites More sharing options...
Author Share Posted July 18, 2020 9 hours ago, ZachSaucier said: It's not working - it still has a lot of errors for me. I am really sorry once again. I accidentally used the same code sandbox for another project. I have replicated the issue I am having in this. Which is when using gsap.utils.toArray to animate multiple elements (the blue and the red text in this case) with the same ref, but the scroll trigger animation only works for one of the element (the red text only.) The working codebox: https://codesandbox.io/s/suspicious-leaf-up3l7?file=/src/App.js I am sorry once again for my ignorance, I appreciate any help because I am struggling to figure this out. Link to comment Share on other sites More sharing options...
Share Posted July 19, 2020 Hi, I am on my mobile so can't really write much code but I belive you just need an array of refs for this to work. Currently you are only animating the last item because that what the anim.current is. Checkout this example on how to create an array or refs in React and use them with ScrollTrigger. https://ihatetomatoes.net/react-and-greensock-tutorial-for-beginners/#5-how-to-create-an-array-of-refs Let me know if that helped. 3 Link to comment Share on other sites More sharing options...
Author Share Posted July 19, 2020 7 hours ago, Ihatetomatoes said: Hi, I am on my mobile so can't really write much code but I belive you just need an array of refs for this to work. Currently you are only animating the last item because that what the anim.current is. Checkout this example on how to create an array or refs in React and use them with ScrollTrigger. https://ihatetomatoes.net/react-and-greensock-tutorial-for-beginners/#5-how-to-create-an-array-of-refs Let me know if that helped. Hellp, thank you for you response. I have tried this earlier on one of my other pages. Thank you for writing this article, it did help. For this particular page, I was hoping for more of a dynamic approach without having to hard code them before, so I can use images, or link elements to another page, and etc. Is there any way to do that? Say even creating multiple refs and/or one trigger ref to be used multiple times on different elements? Link to comment Share on other sites More sharing options...
Share Posted July 19, 2020 That's exactly what the array of refs is used for. You can loop over all the elements inside of each loop and create one ScrollTrigger that will be applied to all elements, but for each element individually. Are you trying to avoid writing ref="something"? So if gsap .toArray worked wouldn't you still need to give your elements a specific class? className="something"? 2 Link to comment Share on other sites More sharing options...
Author Share Posted July 24, 2020 On 7/19/2020 at 5:04 PM, Ihatetomatoes said: That's exactly what the array of refs is used for. You can loop over all the elements inside of each loop and create one ScrollTrigger that will be applied to all elements, but for each element individually. Are you trying to avoid writing ref="something"? So if gsap .toArray worked wouldn't you still need to give your elements a specific class? className="something"? Thank you @Ihatetomatoes for your help again, and I apologize for the late reply. I meant avoid using the map function, if i could use the same ref that that would be perfect so I can style each element seperately. I tried using classname but it does not work. Aside from gsap.utils.toArray, I discovered the the Scroll Trigger Batch method. I gave it a shot trying to implement it in React through useEffect. I have tried following this gsap tutorial on .batch See the Pen zYrxpmb by GreenSock (@GreenSock) on CodePen On my app, It didn't work using the class trigger but using an useRef const worked only on one of the element even tho i set the ref to each element. What am I doing wrong? This is my codepen: https://codesandbox.io/s/scrolltrigger-batch-dijll?file=/src/App.js I added some extra content, and if you scroll down you would be able to see the batched section. I am not getting the error on the codepen but i do get an errorTypeError: element.getBoundingClientRect is not a function and it is pointing at the scrolltrigger batch. I fully understand I can not just add ScrollTrigger.Batch but I do not know how to do it otherwise. Thank you very much in advance! Link to comment Share on other sites More sharing options...
Share Posted July 25, 2020 If I understand your question correctly, this has to do with the fact that timelines must wait 1 tick before doing their initial refresh because if they did it immediately upon creation, they'd be totally empty and there wouldn't be any duration (you haven't populated it with tweens yet), thus when you do your batch() it refreshes BEFORE your timeline-based one which has a pin. The pin essentially adds extra space and pushes things down, so the start/end positions from your batch() haven't accounted for that. The solution should be simple: just add a ScrollTrigger.refresh() right after your .batch() call to manually trigger it. Does that help? 1 Link to comment Share on other sites More sharing options...
Author Share Posted July 31, 2020 On 7/24/2020 at 11:50 PM, GreenSock said: If I understand your question correctly, this has to do with the fact that timelines must wait 1 tick before doing their initial refresh because if they did it immediately upon creation, they'd be totally empty and there wouldn't be any duration (you haven't populated it with tweens yet), thus when you do your batch() it refreshes BEFORE your timeline-based one which has a pin. The pin essentially adds extra space and pushes things down, so the start/end positions from your batch() haven't accounted for that. The solution should be simple: just add a ScrollTrigger.refresh() right after your .batch() call to manually trigger it. Does that help? Thank you the advice. I added a different varible for a different timeline since I do not want the timeline with the batch to have a pin. I really just want a simple y: 100 and fade in box which i was assuming what theonEnter: batch => gsap.from(batch...) did. Is there anywhere else I should add a gsap.to/gasp.form? On the codepen, I have added the Scrolltrigger.refresh() right after my batch calls however, I must be doing something wrong because I made the container height bigger, but none of the other boxes shows up and I do not know if using the same ref is on each div box is working. Would I need to set a trigger on my batch, I have tried that setting the batch ref to the container but that did not work? I apologize for my ignorance I am still struggling with this method, but since one of my page on my app is going to have many boxes, I think it would be more efficient to use batch or even arrays (which I am also clueless about) than individually writing a ref for each box . Thank you for all you guys help! I really appreciate it Link to comment Share on other sites More sharing options...
Share Posted July 31, 2020 29 minutes ago, FarhanSU said: On the codepen, I have added the Scrolltrigger.refresh() right after my batch calls I don't see that. Are you sure? I'm not sure I follow your question. The CodeSandbox you provided seems to work the way I'd expect, especially after adding ScrollTrigger.refresh(); after your batch() call. What am I missing? Can you please provide a minimal demo (if it's not the one you previously provided)? Link to comment Share on other sites More sharing options...
Author Share Posted July 31, 2020 1 hour ago, GreenSock said: I don't see that. Are you sure? I'm not sure I follow your question. The CodeSandbox you provided seems to work the way I'd expect, especially after adding ScrollTrigger.refresh(); after your batch() call. What am I missing? Can you please provide a minimal demo (if it's not the one you previously provided)? Yup, it is still this demo: https://codesandbox.io/s/scrolltrigger-batch-dijll?file=/src/App.js The ScrollTrigger.refresh is on line 66. The problem I was talking about is that, the batch only renders one box, and not the other 9 boxes i wrote. Scrolling past the elements, only the first box appears. I am not sure why the other boxes are not showing up? Thank you once again!! Link to comment Share on other sites More sharing options...
Share Posted July 31, 2020 5 hours ago, FarhanSU said: the batch only renders one box, and not the other 9 boxes i wrote. Scrolling past the elements, only the first box appears. I am not sure why the other boxes are not showing up? console.log(agencyReveal) and see what it gives you - it's just the one element. Fix your ref to refer to all of your boxes and it should work. Link to comment Share on other sites More sharing options...
Author Share Posted July 31, 2020 6 hours ago, ZachSaucier said: console.log(agencyReveal) and see what it gives you - it's just the one element. Fix your ref to refer to all of your boxes and it should work. Hello @ZachSaucier, I put the console log right before my return, and the console.log points the ref to Object {current: HTMLDivElement} current: <DIV class="box" style="transform: translate(0px, 100px);"></DIV> I am not sure what to do with that information since its not telling me something is wrong. Should it have said array instead of an object? 😕 Link to comment Share on other sites More sharing options...
Share Posted July 31, 2020 11 hours ago, FarhanSU said: Yup, it is still this demo: https://codesandbox.io/s/scrolltrigger-batch-dijll?file=/src/App.js The ScrollTrigger.refresh is on line 66. It wasn't there when I checked (maybe a caching thing?). Even now, it's incorrect - you literally have it inside your .batch() call as a parameter It belongs AFTER the .batch() call. But that has nothing to do with the fact that it's only handling one box. That's a React question. I have almost no experience with React, but from a quick Google search, it looks like you've gotta create your own Array and then add references like this: // BAD: <div ref={agencyReveal} className="box" /> <div ref={agencyReveal} className="box" /> // GOOD: const agencyReveal = []; <div ref={(el) => {agencyReveal.push(el)}} className="box" /> <div ref={(el) => {agencyReveal.push(el)}} className="box" /> https://codesandbox.io/s/scrolltrigger-batch-qxh0r?file=/src/App.js Again, I could be wrong about the React stuff. You'll need to verify the React-specific stuff since these forums are really supposed to be about GSAP-specific questions. I hope that helps! 1 Link to comment Share on other sites More sharing options...
Share Posted July 31, 2020 2 minutes ago, GreenSock said: // BAD: <div ref={agencyReveal} className="box" /> <div ref={agencyReveal} className="box" /> // GOOD: const agencyReveal = []; <div ref={(el) => {agencyReveal.push(el)}} className="box" /> <div ref={(el) => {agencyReveal.push(el)}} className="box" /> No, don't do that. If you're using regular variables inside React Hooks, you're probably doing it wrong. And don't do this. // BAD const tl = useRef(gsap.timeline({ paused: false })); const sl = useRef(gsap.timeline()); // GOOD const tl = useRef(); const sl = useRef(); You can do this to get the agencyReveal elments. agency.current.children 1 Link to comment Share on other sites More sharing options...
Share Posted July 31, 2020 Thanks for clarifying, @OSUblake. I thought of the .children thing, but I thought React is super strict about element references (not using direct ones) and would frown on that. Obviously I have no idea what I'm talking about when it comes to React Link to comment Share on other sites More sharing options...
Share Posted July 31, 2020 8 minutes ago, GreenSock said: I thought React is super strict about element references Nah. It's not strict at all. Most people just aren't using React the way it's documented. 1 Link to comment Share on other sites More sharing options...
Author Share Posted August 1, 2020 Thank you very much @GreenSock and @OSUblake for clarifying both the tl ref (which is good because I can fix that on the other pages) and the .children prop. I am not sure why using ref={agencyReveal.current.children} on my box elements results in an error that says agencyReveal.current is undefined. I also tried using React.createRef but the issue is still there. I have updated my codepen here: https://codesandbox.io/s/scrolltrigger-batch-dijll?file=/src/App.js However, the code written by @GreenSock using ref={el => agencyReveal.push(el);}} works On 7/31/2020 at 4:23 PM, GreenSock said: https://codesandbox.io/s/scrolltrigger-batch-qxh0r?file=/src/App.js Thank you all very much for your patience, I appreciate it immensenly! Link to comment Share on other sites More sharing options...
Share Posted August 1, 2020 20 minutes ago, FarhanSU said: ref={agencyReveal.current.children} That's not all what I meant. const agency = React.createRef(); useEffect(() => { sl.current = ScrollTrigger.batch(agency.current.children, { ... }); <div ref={agency} className="layerfour"> <div className="box" /> <div className="box" /> <div className="box" /> <div className="box" /> <div className="box" /> <div className="box" /> <div className="box" /> <div className="box" /> <div className="box" /> </div> 3 Link to comment Share on other sites More sharing options...
Author Share Posted August 1, 2020 Oh wow I completely misunderstood what you meant, I was thinking referencing to each div as the children component. Thank you so much @OSUblake, you're a life saver, it is working perfectly rn!!! 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