Jump to content
Search Community

GoodMorning

Members
  • Posts

    9
  • Joined

  • Last visited

Everything posted by GoodMorning

  1. Thanks everyone for your help! Sorry about the super specific framework-based question. I've come up with a new way that should hopefully be better, where I plan on making use of multiple timelines, having a function that will create a timeline for each card with added labels, and pause/play starting at a specific label depending on its starting position. I did have a quick question though about timelines, and was wondering if it would be a bad idea to have multiple (5) timelines playing at the same time.
  2. One idea I had is to have a separate timeline for each card, with the steps of locations included. Then, I would step through my various timelines whenever the button is clicked, and allow for it to repeat. I'm not sure if that's a better plan.
  3. Sorry for the delay, here is my codesandbox, but it does not work fully here. The animation works once, and then we get the error I was initially getting. Locally, I am able to repeat the animation as I intended until I import another library which does something else. https://codesandbox.io/s/mystifying-poitras-egmy38?file=/pages/index.tsx Here is a video of how it works locally: https://www.loom.com/share/252cd98a568e4aa58ee1e619d681bb57
  4. Hi everyone! I have a cycling carousel animation where I move elements to a new position, and then change the refs of each element to effectively "reset" the animation but with a new starting position. However, I'm not sure if I'm implementing it in the best way. That's because I'm running into the following error in parts of my code "GSAP target undefined not found." I'm using an array of refs and they are assigned to divs in a map function within React. {cardIdx.map((cardI) => { return ( <div ref={el => cardRefs.current[cardI] = el} className={styles.card}/> )} Thanks for any help or insight into what might be a better alternative. Here's what I'm currently doing: (Next.js + Typescript) const [order, setOrder] = useState([2, 1, 3, 5, 4]) useEffect(() => { if (typeof window !== "undefined") { gsap.set(cardRefs.current[order[2]], { removed }); gsap.set(cardRefs.current[order[1]], { removed }); gsap.set(cardRefs.current[order[3]], { removed }); gsap.set(cardRefs.current[order[0]], { removed }); gsap.set(cardRefs.current[order[4]], { removed }); } // animateButtonRight(); }, [width]) const animateButtonRight = () => { console.log('run animation') gsap.timeline({ onComplete: () => { let newOrder: number[] = order; newOrder.unshift(newOrder.pop()!); setOrder(newOrder) } }) .set(buttonRef.current, { disabled: true }) .to(cardRefs.current[order[3]], { removed }) .set(cardRefs.current[order[3]], { removed }) .to(cardRefs.current[order[2]], { removed }, 0) .to(cardRefs.current[order[1]], { removed }, 0) .to(cardRefs.current[order[0]], { removed }, 0) .set(buttonRef.current, { disabled: false }) }
  5. Ok so Instead of using states, I simply used gsap.set(buttonRef.current, {disabled:true}) inside of the timeline which served the same purpose. I'm not sure how to handle states in the future, but this worked for now.
  6. I'm not trying much beyond attempting to animate divs on a button click, and disable the button on animation start + re-enable when the animation is complete. It's a simple timeline with changes to the right, left, bottom, and rotation properties. In this new component, the animation works with the lines in the onStart/onComplete commented out, but as soon as I attempt to set a state there, the animation doesn't run. I have a video of the behavior not working correctly when I use states: Link I don't know if this is helpful but here is pretty much the complete context to the situation: function CardCarousel({ className }: Props) { // Middle Card let cardOneRef = useRef<HTMLDivElement>(null); // Left Card let cardTwoRef = useRef<HTMLDivElement>(null); // Right Card let cardThreeRef = useRef<HTMLDivElement>(null); // Left Offscreen Card let cardFourRef = useRef<HTMLDivElement>(null); // Right Offscreen Card let cardFiveRef = useRef<HTMLDivElement>(null); let tempDiv = useRef<HTMLDivElement>(null); let width = useWindowSize(); const distanceFromEdgeBottomM = "-40%"; const distanceFromEdgeLR = "5%"; const distanceFromEdgeBottomLR = "-50%"; const offscreenDistanceFromEdgeBottom = "-70%"; const offscreenDistanceFromEdgeLR = "-20%"; // Have this update on screen width change useEffect(() => { if (typeof window !== "undefined") { gsap.set(cardOneRef.current, { left: width / 2 - width * 0.22 / 2, bottom: distanceFromEdgeBottomM, rotation: 0 }); gsap.set(cardTwoRef.current, { left: distanceFromEdgeLR, bottom: distanceFromEdgeBottomLR, rotation: -9, transformOrigin: "left 50%" }); gsap.set(cardThreeRef.current, { right: distanceFromEdgeLR, bottom: distanceFromEdgeBottomLR, rotation: 9, transformOrigin: "right 50%" }); gsap.set(cardFourRef.current, { left: offscreenDistanceFromEdgeLR, bottom: offscreenDistanceFromEdgeBottom, rotation: -18, transformOrigin: "left 50%" }); gsap.set(cardFiveRef.current, { right: offscreenDistanceFromEdgeLR, bottom: offscreenDistanceFromEdgeBottom, rotation: 18, transformOrigin: "right 50%" }); } }, [width]) function animateButtonRight() { gsap.timeline({ // onStart: () => setRightDisabled(true), onComplete: () => { tempDiv = cardFiveRef; cardFiveRef = cardThreeRef; cardThreeRef = cardOneRef; cardOneRef = cardTwoRef; cardTwoRef = cardFourRef; cardFourRef = tempDiv; // setRightDisabled(false); } }) .to(cardThreeRef.current, { left: "", right: offscreenDistanceFromEdgeLR, bottom: offscreenDistanceFromEdgeBottom, rotation: 18, duration: 1.0, ease: Power3.easeInOut, transformOrigin: "right 50%" }) .set(cardThreeRef.current, { left: offscreenDistanceFromEdgeLR, right: "", bottom: offscreenDistanceFromEdgeBottom, rotation: -18, transformOrigin: "left 50%" }) .to(cardOneRef.current, { left: "", right: distanceFromEdgeLR, bottom: distanceFromEdgeBottomLR, rotation: 9, duration: 1.0, ease: Power3.easeInOut, transformOrigin: "right 50%", delay: 0.1 }, 0) .to(cardTwoRef.current, { right: "", left: width / 2 - width * 0.22 / 2, bottom: distanceFromEdgeBottomM, rotation: 0, duration: 1.0, ease: Power3.easeInOut, delay: 0.2 }, 0) .to(cardFourRef.current, { right: "", left: distanceFromEdgeLR, bottom: distanceFromEdgeBottomLR, rotation: -9, duration: 1.0, ease: Power3.easeInOut, delay: 0.3, transformOrigin: "left 50%" }, 0) } return ( <div className={classnames(styles.CardCarousel, className)}> <button onClick={animateButtonRight}>Move</button> <div ref={cardOneRef} className={styles.card}><h1>This is main initial text</h1></div> <div ref={cardTwoRef} className={styles.card}><h1>This is left initial text</h1></div> <div ref={cardThreeRef} className={styles.card}><h1>This is right initial text</h1></div> <div ref={cardFourRef} className={styles.card}><h1>This is offscreen left initial text</h1></div> <div ref={cardFiveRef} className={styles.card}><h1>This is offscreen right initial text</h1></div> </div> ) }
  7. Hi! I'm using GSAP with React + Typescript and have a basic animation where I move a few elements on the click of a button. However, I noticed that the animation glitches out when the button is pressed again before the animation has fully completed. So, I decided to add a state that would disable the button on the start of the animation, and re-enable it upon completion. However, this seems to have broken the animation to the point where it won't function at all. Thanks for any help! Here's the function I use on button click: function animateButtonRight() { gsap.timeline({ onStart: () => setRightDisabled(true), onComplete: () => { tempDiv = cardFiveRef; cardFiveRef = cardThreeRef; cardThreeRef = cardOneRef; cardOneRef = cardTwoRef; cardTwoRef = cardFourRef; cardFourRef = tempDiv; setRightDisabled(false); } }) .to(cardThreeRef.current, { left: "", right: offscreenDistanceFromEdgeLR, bottom: offscreenDistanceFromEdgeBottom, rotation: 18, duration: 1.2, ease: Power3.easeInOut, transformOrigin: "right 50%" }) .set(cardThreeRef.current, { left: offscreenDistanceFromEdgeLR, right: "", bottom: offscreenDistanceFromEdgeBottom, rotation: -18, transformOrigin: "left 50%" }) .to(cardOneRef.current, { left: "", right: distanceFromEdgeLR, bottom: distanceFromEdgeBottomLR, rotation: 9, duration: 1.2, ease: Power3.easeInOut, transformOrigin: "right 50%", delay: 0.2 }, 0) .to(cardTwoRef.current, { right: "", left: width / 2 - width * 0.22 / 2, bottom: distanceFromEdgeBottomM, rotation: 0, duration: 1.2, ease: Power3.easeInOut, delay: 0.4 }, 0) .to(cardFourRef.current, { right: "", left: distanceFromEdgeLR, bottom: distanceFromEdgeBottomLR, rotation: -9, duration: 1.2, ease: Power3.easeInOut, delay: 0.6, transformOrigin: "left 50%" }, 0) }
  8. Thank you, the issue was not using .current
  9. Hi! I've just started learning GSAP but I haven't been able to get anything to move/animate. I'm using NextJS with Typescript and here's an example of something I've done. Nothing is moving at all, and I've also tried using TweenMax. Any help would be much appreciated. import type { NextPage } from 'next' import Head from 'next/head' import { useRef, useEffect } from 'react'; import { gsap, Power3 } from 'gsap'; const Home: NextPage = () => { let el = useRef<HTMLDivElement>(null); useEffect(() => { gsap.from(el, {duration: 0.7, opacity: 0, x: 40, ease:Power3.easeOut}) }, []) return ( <div > <Head> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <main > <div ref={el} style={{width:"75px", height: "75px", backgroundColor: "white"}}/> </main> </div> ) } export default Home
×
×
  • Create New...