Jump to content
Search Community

flowen

Members
  • Posts

    87
  • Joined

  • Last visited

Everything posted by flowen

  1. So I fixed here it by looping and creating multiple scrolltriggers. Just wondering if this is really bad for performance / how it could be optimised. Especially because I plan to add more sophisticated timelines (animating the 3d model, etc) to each section while/when scrolling to it
  2. just noticed that in the video, in the pinning example, also a scrollTrigger is created for each section (panel). I'm confused. Should, or shouldn't I do this?
  3. so i've been playing around with your code. And I'm still confused how to optimise the scrolltrigger for multiple sections. So I have multiple sections on my page and I want to use each section as a trigger for the elements in that section (right now the headings which I have split with splittingjs). Wouldn't I still need to create multiple scrollTrigger instances so I have a different trigger element (section) for the animations within that? I'm not quite sure I understand how to optimise this. In your code you refer to section as the trigger, which I suppose also means that you create multiple timelines in the loop that returns section (sections.foreach(section => ())). If you meant the whole array (sections), I tried that and it won't trigger anything. Something else I noticed is that animating all the characters that are split is bad for performance. So I choose to use CSS, with a class, instead. Saw in the video I should probably use the onEnter hook, as I don't think I can use toggleClass to just fire it once, right?
  4. ahh I really needed these videos. I was assuming the api was completely different, thinking I should create a scrolltrigger for each tween. This really helps, thanks for pointing out the mistakes I made ?
  5. as the title says. Please have a look here for the code So the text-animations are triggered at the same time as the markers suggest. When I loop though, the target is updated when I log out the values (see console output). Also playing around with the start, stop positions I get very strange results. thanks for having a look!
  6. instant bookmark, all the best with your new project!
  7. So for NPM and Yarn packages I basically update through their CLI's. But what's the best way to make sure I got the latest gsap-bonus plugins? Can I get notified somehow?
  8. thank for the great examples @mikel !
  9. @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 !
  10. 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.
  11. 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
  12. /** * 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?
  13. 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?
  14. 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'
  15. 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.
  16. 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
  17. The unpause trick did it and definitely gonna simplify the useeffect stuff thanks @Rodrigo for helping me out with React (once again)
  18. 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 ( <> ... </> ) }
  19. Oh, wow, what a timing! I'll have to upgrade of course Thanks for mentioning and thanks for the explanation on the chain!
  20. @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)
  21. 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
  22. @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!
  23. as the title says.. Here's the debug version of the codepen. Click to replay, you see it every time at the end of the animation
  24. @StefanHinck I stayed with TransitionLink because it offered me the customization I needed for my animations. Anilink doesnt and its made for some quick out-of-the-box page-transitions but not much more than that. I had a quick look in the docs and I see no support for length of the animation The dev himself admits he really doesn't want you to use it No worries, we all start somewhere. I "should" be using chrome's debugger tools after 10years of frontend but still love console.log haha So: AniLink for some quick page transitions transitionLink for some cool custom work
×
×
  • Create New...