Jump to content

Search In
  • More options...
Find results that contain...
Find results in...


  • Content Count

  • Joined

  • Last visited

Community Reputation

16 Newbie

1 Follower

About flowen

  • Rank
    Advanced Member

Contact Methods

Profile Information

  • Gender
  • Location
    anywhere my iphone is

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. thank for the great examples @mikel !
  2. @mikel didn't know that was possible! Interesting way to approach, though I don't understand the creation of the path (yet). Although for now I've seemed to have fixed it by making the svg responsive. The reason why my svg wasn't responsive is that React was removing the 'viewbox' attribute. It was supposed to be 'viewBox'. Took me half a day to find as there was no error ? also thanks @ZachSaucier !
  3. Another motion path issue, this time with a codepen So I have this fartpillow animating in from the right (outside of the screen) triggered by an intersection observer. On smaller screens the fartpillow jumps out of the screen and I can't seem to get the motion path resize correctly. The final implementation is in React, but I'm using pretty much the exact same code from this prototype. One of the challenges is that I want the animation to start outside of the container as well, but I somehow (not sure how) fixed this. Just thinking ahead that this might be another challenge if the path fits to size within the container.
  4. Sorry I can't share the actual code, but I have a deploy you can see live here When the motion path animation starts, "YES" suddenly changes position to the far right. What are some things I could look at to make sure this doesn't happen? The svg including the motion path is styled fixed with a 100% width and height The parents of the element Yes has absolute positioning and is rotated, perhaps there's an issue there? I know this is far from perfect to help me debug, but right now I can't offer more. bullet.mp4
  5. /** * setup Gsap animation */ useEffect(() => { if ( !refWrapperLarge.current || !refWrapperSmall.current || !refWrapperBorder.current || !refText.current || !refRectLargeRight.current ) return // animation code }, [ refWrapperLarge.current, refWrapperSmall.current, refWrapperBorder.current, refText.current, refRectLargeRight.current, ]) This month I've been coding a lot in React hooks (in Gatsby env) with GSAP. But I keep coming across the above (anti-)pattern. I wondered if perhaps someone had a better solution or idea how this could be done. So if you're not familiair with the useEffect hook, it's a piece of code that keeps re-running when for examples values (or state) changes. Which can be super-useful in apps. But in order to animate elements with GSAP, I kept coming back to this pattern. I first need to check if all refs exists (they're primarily defined with the useRef() hook). On the first run they do not, since the component is still being rendered. In the dependency array I add the refs as well, so it will re-run, until all DOM elements exists. Only then can I start animating the components. @Rodrigo you have any idea/suggestion?
  6. https://greensock.com/docs/v3/GSAP/gsap.to() There's no mention of the available options for the advanced stagger options. Instead there's a broken link to a codepen, which I think should be this one? I feel like the docs are not completely updated yet? Just wanna help out here and there, not sure if the forum is the best way to do this. edit: I created a link in the post, but instead it auto-formatted it to normal text?
  7. it's on the page I linked too. If you scroll down you see `GSAP 3 Install Helper` and it's not listed under the checkbox 'plugins'
  8. I solved a question I wanted to post, but instead noticed the docs are incomplete for the scrollTo Plugin It's not on the install helper tool and thought the scrollTo plugin was enabled by default.
  9. ah! I had a similar issue. I looked in the docs and there it told me to get a 'linear.easeNone' or 'power0.easeNone' but neither of those worked. as well as in the ease visualiser if you click power0
  10. The unpause trick did it and definitely gonna simplify the useeffect stuff thanks @Rodrigo for helping me out with React (once again)
  11. I have a different problem now.. I'll keep it in this topic as the topic is still correct. - I have multiple paused timelines, that I add to a master timeline. - I pause them, otherwise they're being playing during initialisation.. right? - I start playing the master timeline once all state is set, but nothing happens. I think because the child timelines are still paused... could this be? Due to the nature of useEffect effects, I think I'm supposed to set them up like this: - Check if the timeline exists (first time this fails, so we return) - timeline is being set so we rerun the effect - add them with a setter const Intro = () => { const [tlIntroMaster, setTlIntroMaster] = useState(null) const [tlIntro, setTlIntro] = useState(null) const [tlLoop, setTlLoop] = useState(null) useEffect(() => { setTlIntro( gsap .timeline({ defaults: { duration: 0.2, repeat: 0 } }) ... ) setTlLoop( // it's important this one repeats gsap .timeline({ defaults: { duration: 0.25 }, repeat: -1, paused: true }) ... ) }, []) // here I add them to setTlIntroMaster useEffect(() => { if (!tlLoop || !tlIntro) return setTlIntroMaster( gsap .timeline() .add(tlIntro) .add(tlLoop) ) }, [tlLoop, tlIntro]) // this use effect reruns when the tlIntroMaster has a timeline // we play it.. but it won't play. // the children are still in a paused state and I can't seem to run them useEffect(() => { if (!tlIntroMaster) return // I log to see if something is there - yes console.log(tlIntroMaster) tlIntroMaster.play() }, [tlIntroMaster]) return ( <> ... </> ) }
  12. Oh, wow, what a timing! I'll have to upgrade of course Thanks for mentioning and thanks for the explanation on the chain!
  13. @zachSaucier thx for the pen, that's a useful callback. Would you recommend the Beta of 3 over gsap 2 ? ps: I also wondered.. why the chain of seek, pause and kill (and not just kill for example)
  14. Right now I unfortunately don't have a codebox/pen with my latest try at it, but hopefully the example will help a bit until I upload the full code. https://codesandbox.io/s/smoosh-violet-fk6un (this example is pure js, no react) So I have: - a Master timeline. - smaller timelines added to the master timeline - 2 labels - I use a .add(fn) with a condition in it to either play the loop again or go to 'end' label. I would like to use this with a (img) preloader. So whenever loading is finished, I want the loop to go to 'end'. - end (infinite) loop The problem I faced so far is that the 'loop' variable, which is state in React, somehow doesn't work in the conditional in the .add function. So I tried hacking this by adding each timeline to their own state, add them to the master and instead of a conditional for 'loop', I add a 'seekloop'. Then set state of 'loop', rerun the effect and this time remove the 'seekloop' and add a different seek. I hope this makes sense ? import React, { useEffect, useRef, useState } from "react" import { TweenMax, TimelineLite, Power3, Linear, Back } from "gsap" import { Wrap, WrapText, YesWrapper, Yes, Problem, ProblemText, ProblemYes, BG, } from "./styles" const Intro = () => { const [{ w, h }, setWindowSize] = useState({ w: window.innerWidth, h: window.innerHeight, }) const [loop, setLoop] = useState(true) const [aspect, setAspect] = useState(true) const [tlMaster, setAnimation] = useState(null) const [tlIntro, setTLIntro] = useState(null) const [tlLoop, setTLLoop] = useState(null) const [tlEnd, setTLEnd] = useState(null) const hyp = Math.sqrt(w * w + h * h) const angle = Math.floor(Math.sin(h / hyp) * (180 / Math.PI)) const bounce = Back.easeOut.config(0.05) const refWrap = useRef(null) const refWrapText = useRef(null) const refYesWrapper = useRef(null) const refProblemText = useRef(null) const refProblemYes = useRef(null) const refBG = useRef(null) // initial effect to load and measure useEffect(() => { function init() { setWindowSize({ w: window.innerWidth, h: window.innerHeight }) TweenMax.set(refProblemText.current, { yPercent: 100 }) TweenMax.set(refYesWrapper.current, { y: h }) } window.addEventListener("resize", init) return () => window.removeEventListener("resize", init) }, [h]) useEffect(() => { setAspect(w / h) TweenMax.set(refWrapText.current, { xPercent: aspect > 1 ? 5 : 35, width: h, }) }, [w, h]) useEffect(() => { setAnimation(new TimelineLite({ repeat: 0, paused: true })) }, []) useEffect(() => { if (!tlMaster) return setTLIntro( new TimelineLite() .fromTo(refBG.current, 0.2, { y: 0 }, { y: h / 2 }) .to(refWrap.current, 0.2, { rotation: -angle }) .to(refProblemText.current, 0.2, { yPercent: 0, opacity: 1 }) .staggerFromTo( refYesWrapper.current.childNodes, 0.2, { y: -h }, { opacity: 1, y: 0, ease: bounce }, -0.1 ) ) }, [tlMaster]) useEffect(() => { if (!tlMaster) return setTLLoop( new TimelineLite() .to(refProblemText.current, 0.2, { x: w * 1.5 }) .to(refProblemYes.current, 0.2, { yPercent: 100 }) .staggerTo( refYesWrapper.current.childNodes, 0.2, { yPercent: 100, opacity: 1, y: 0, ease: bounce }, -0.1 ) .set(refProblemText.current, { x: 0, yPercent: 100 }) .to(refProblemText.current, 0.2, { yPercent: 0 }) .delay(0.3) ) }, [tlMaster]) useEffect(() => { if (!tlMaster) return const completedIntro = () => { TweenMax.to(refWrapText.current, 2, { y: 100, ease: Linear.easeNone, }).repeat(-1) //y:100 = yesHeight // dom.html.classList.remove("js--disable-scroll"); } setTLEnd( new TimelineLite({ onComplete: completedIntro }) .addLabel("start") .to(refWrap.current, 0.6, { rotation: -90 }, "start") .to( refWrap.current, 0.6, { xPercent: 100, ease: Power3.easeOut }, "start" ) .to( refWrapText.current, 0.6, { xPercent: aspect > 1 ? "-=5" : "-=35", ease: Power3.easeOut }, "start" ) ) }, [tlMaster]) useEffect(() => { if (!tlIntro || !tlLoop || !tlEnd) return tlMaster .add(tlIntro) .addLabel("loop") .add(tlLoop) .addLabel("end") .add(tlEnd) tlMaster.play(0) }, [tlIntro, tlLoop, tlEnd]) useEffect(() => { if (!tlMaster || !tlLoop) return if (loop) { console.log("add") tlLoop.add(() => tlMaster.seek("loop"), "seekLoop") setLoop(false) } else { console.log("remove") tlMaster.removeLabel("seekLoop") tlLoop.add(() => tlMaster.seek("end")) } }, [tlMaster, tlLoop, loop]) return ( <Wrap ref={refWrap}> <WrapText ref={refWrapText}> <YesWrapper ref={refYesWrapper}> <Yes>Yes</Yes> <Yes>Yes</Yes> <Yes>Yes</Yes> <Yes>Yes</Yes> <Yes>Yes</Yes> <Yes>Yes</Yes> <Yes>Yes</Yes> <Yes>Yes</Yes> </YesWrapper> <Problem> <ProblemYes ref={refProblemYes}>Yes</ProblemYes> <ProblemText ref={refProblemText}>problem</ProblemText> </Problem> </WrapText> <BG ref={refBG} /> </Wrap> ) } export default Intro
  15. @ZachSaucier Thanks you for this lib @GreenSock Thanks for explaining Jack! Well I kept working on the animation and now I ended the animation in an infinite loop. So I'm not seeing the problem anymore. But good to know how the rendering works and I'll keep the solution in mind!