nonoumasy Posted January 31, 2021 Share Posted January 31, 2021 I used this as a guide for ScrollTrigger and React with dynamic data being mapped. https://ihatetomatoes.net/react-and-greensock-tutorial-for-beginners/ So it sort of works. Sort of. My code is pretty much the same as the demo above except I'm fetching data from Firebase Firestore with a useEffect to fetch the data and then to invoke the GSAP animation. A Couple of things: 1) just like the demo, my headerRef does animate (and that is using the fetched data) but only that. The array of items that is mapped from the fetched data doesn't get the animation. 2)also, something wierd, if I make a change and save my React app, this will actually make the animation work, but as soon as I hit refresh on the browser, it goes back to not working. I've turned the markers on and I only see them at this time. 3)I would have added a CodePen but since this requires a Firebase and React, I thought I would just paste the relevant code below: Hope someone can help. const DetailScreen = ({ }) => { const headerRef = useRef(null); const { id } = useParams() const [journal, setJournal] = useState([]) const [chapters, setChapters] = useState([]) const revealRefs = useRef([]); revealRefs.current = []; const addToRefs = el => { if (el && !revealRefs.current.includes(el)) { revealRefs.current.push(el); } }; useEffect(() => { fetchData() gsapAnim() }, []) const fetchData = async () => { const db = firebase.firestore() const data = await db.collection('trips').doc(id).get() const item = data.data() const data2 = await db.collection('trips').doc(id).collection('chapters').get() const item2 = data2.docs.map(doc => (doc.data())) setJournal(item) setChapters(item2) } const gsapAnim = () => { gsap.from(headerRef.current, { autoAlpha: 0, ease: 'none', delay: 1 }); chapters && revealRefs.current.map((el, index) => { gsap.fromTo(el, { autoAlpha: 0 }, { duration: 1, autoAlpha: 1, ease: 'none', scrollTrigger: { id: `section-${index + 1}`, trigger: el, start: 'top center+=100', toggleActions: 'play none none reverse', markers: 'true' } }); }); } return ( <div className={"detailContainer"}> <div ref={headerRef} className={"headerSection"}> <img className={"journalImage"} src={journal.journalImage} alt='' /> <h2 className={"title"}>{journal.title}</h2> <h4 className={"author"}>{journal.author}</h4> <div className={"tagsSection"}> {journal.tags && journal.tags.map(tag => (<Tags tag={tag} />))} </div> <div className={"summarySection"}> <div style={{ fontSize: 24, fontWeight: 'bold' }}>Summary:</div> <div className={"summary"}> {journal.summary} </div> </div> </div> <div className={"entrySection"} style={{ marginTop: 120, }} > {chapters.map(item => ( <div key={item.id} ref={addToRefs}> <Entry item={item} /> </div> ))} </div> </div> ) } Link to comment Share on other sites More sharing options...
Solution ZachSaucier Posted February 1, 2021 Solution Share Posted February 1, 2021 Hey nonoumasy. On 1/31/2021 at 6:32 AM, nonoumasy said: my headerRef does animate (and that is using the fetched data) but only that. The array of items that is mapped from the fetched data doesn't get the animation. To me that makes it sound like you're not waiting for your data to load before trying to start your animation. Looking at your code, that seems to be the case - you don't wait for your data to be fetched before starting your animation. Link to comment Share on other sites More sharing options...
nonoumasy Posted February 1, 2021 Author Share Posted February 1, 2021 That was exactly it. I added the gsap() function after setChapters() in the fetchData function and now it works some of the time. Can you pls take a look at : https://tripmap.netlify.app/journals/gGKrNrmT8JAYDSqBBt0X Sometimes the section has more height sometimes less. Is this still part of the problem of not waiting for the fetched data? I added awaits on most of the fetching stuff so I'm not sure what else I can do to make sure the state is finished before calling the GSAP function. FYI, on mobile its not that bad. the sections end in the right place. thanks. Link to comment Share on other sites More sharing options...
nonoumasy Posted February 2, 2021 Author Share Posted February 2, 2021 Ok, i finally fixed this with useEffect(() => { fetchData() setTimeout(()=> { gsapAnim() }, 1000); }, []) so that 1 second gave it just enough time to fetch the data. still not sure if the array had more items if this trick would work. Link to comment Share on other sites More sharing options...
ZachSaucier Posted February 2, 2021 Share Posted February 2, 2021 Guessing what time it's loaded is not a good way of doing things. Why not call gsapAnim as the last line of your fetchData function? Link to comment Share on other sites More sharing options...
nonoumasy Posted February 2, 2021 Author Share Posted February 2, 2021 I did add it last. The only way i could make it work was to add a little timeout. useEffect(() => { fetchData() setTimeout(()=> { gsapAnim() }, 1000); }, []) const fetchData = async () => { const db = firebase.firestore() const data = await db.collection('trips').doc(id).get() const item = await data.data() const data2 = await db.collection('trips').doc(id).collection('chapters').get() const item2 = await data2.docs.map(doc => (doc.data())) await setJournal(item) await setChapters(item2) // await gsapAnim() } const gsapAnim = () =>{ gsap.from(headerRef.current, { autoAlpha: 0, ease: 'none', delay: 1 }); revealRefs?.current?.map((el, index) => { gsap.fromTo(el, { autoAlpha: 0 }, { duration: 1, autoAlpha: 1, ease: 'power2', scrollTrigger: { id: `section-${index + 1}`, trigger: el, start: 'top center+=0', end: 'bottom top', toggleActions: 'restart none none reverse', // markers: 'true', scrub: 'true', } }); }); } Link to comment Share on other sites More sharing options...
ZachSaucier Posted February 2, 2021 Share Posted February 2, 2021 Are you saying that you removed the gsapAnim call from your useEffect, uncommented it inside of the fetchData function, and it didn't work the way that you want it to? Link to comment Share on other sites More sharing options...
nonoumasy Posted February 2, 2021 Author Share Posted February 2, 2021 I tried both. I added gsapAnim to fetchData which was called in useEffect. That didnt work so I just added it after fetchData in the useEffect. and that didnt work either, well sometimes it did, but not consistent. Then when I added the useTimeout, it did work. Link to comment Share on other sites More sharing options...
nonoumasy Posted June 1, 2021 Author Share Posted June 1, 2021 Finally got this scrollTrigger to work. Demo:https://oocbl.sse.codesandbox.io/ 2 Link to comment Share on other sites More sharing options...
OSUblake Posted June 1, 2021 Share Posted June 1, 2021 For anyone else coming across this, here's a post that shows how to fetch data and then create your animations. 1 Link to comment Share on other sites More sharing options...
nonoumasy Posted June 1, 2021 Author Share Posted June 1, 2021 Here is the code I used that worked with NextJS: (however, this didn't work for me in a React app)...any ideas? import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/dist/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); import data from '../data' export default function ReactComponent () { //GSAP section const revealsRef = useRef([]); revealsRef.current = []; useEffect(() => { revealsRef?.current.map((el, index) => { gsap.fromTo( el, { autoAlpha: 0 }, { duration: 1, autoAlpha: 1, ease: "power2", scrollTrigger: { id: `section-${index + 1}`, trigger: el, start: "top center+=300", end: "bottom top", toggleActions: "restart none none reverse", // markers: "true", scrub: "true" } } ); }); }, []); const addToRefs = (el) => { if (el && !revealsRef.current.includes(el)) { revealsRef.current.push(el); } }; //end of GSAP section return ( <> {data.map((item) => { return ( <div ref={addToRefs} key={item.id}> ... </div> ) } </> ) ) } Link to comment Share on other sites More sharing options...
OSUblake Posted June 1, 2021 Share Posted June 1, 2021 What didn't work? There should be no difference between React and NextJS. Do you have codesandbox showing the issue? Link to comment Share on other sites More sharing options...
nonoumasy Posted June 2, 2021 Author Share Posted June 2, 2021 https://codesandbox.io/s/travel-conditions-wj96q?file=/src/components/GridComponent.js I used the same code for a Nextjs however it doesn't seem to work for this React app. If I save, then it will (sort of) work until a refresh. The GSAP part is in the component/GridComponent Link to comment Share on other sites More sharing options...
OSUblake Posted June 2, 2021 Share Posted June 2, 2021 I'm having a hard time getting that to even load, but I think part of the problem is that you are using TypeScript syntax in JavaScript files. Try changing the files to TypeScript extensions, or get rid of the TypeScript syntax, like the ? marks. // TypeScript revealsRef?.current.map // JavaScript revealsRef.current.map 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