Jump to content
Search Community

Devotee007

Members
  • Posts

    74
  • Joined

  • Last visited

Posts posted by Devotee007

  1. Thanks for the reply! :)

    I tried it, but I get the same result after changing it to overflow:hidden. The scroll keeps on going but it doesn't repeat directly from the top, there's a long gap before the text starts over from the top. It should be on going without the gap. 

  2. I don't get why this text gets blurry and jmupy on scale. I have done this before without this problem. It seems I can't use willChange anymore. The animation won't work at all then. The font is thin I know, but I have tried with different fonts, same result. What am I missing? 

     

     

    See the Pen ZEVqobP by Devotee007 (@Devotee007) on CodePen

  3. 9 hours ago, GreenSock said:

    There are other ways to do it too, like using CSS variables or a proxy object that animates a raw string and applies it in an onUpdate. 


    I would really appreciate if you could show me an example of this. 

  4. I got it to work now! :) Thanks @Cassie and @Rodrigo for the input and help!

    Working code:
     

      const mobileMenu = useRef<HTMLDivElement>(null);
      const menuTl = useRef<GSAPTimeline>(gsap.timeline());
    
      const toggleMobileMenu = () => {
        if (menuTl.current !== null) {
          menuTl.current.reversed(!menuTl.current.reversed());
    
          setTopMenuVisible(!activeMobileTopMenu);
          setActiveSubLevel(-1);
          setActiveSubSubLevel(-1);
        }
      };
    
      useLayoutEffect(() => {
        const ctx = gsap.context(self => {
          menuTl.current = gsap.timeline({ paused: true });
          menuTl.current.to(
            ".js-mobile-overlay",
            {
              // yPercent: 170,
              y: "85vh",
              ease: "expo.inOut",
              duration: 1.1
            },
            0
          );
    
          menuTl.current.to(
            ".js-mobile-menu",
            {
              y: 0,
              ease: "expo.inOut",
              duration: 0.9
            },
            0.1
          );
    
          menuTl.current.to(
            ".js-pie-top",
            {
              strokeDasharray: "0,100",
              autoRound: false,
              ease: "expo.in",
              duration: 0.5
            },
            0.1
          );
    
          menuTl.current.to(
            ".js-pie-bottom",
            {
              strokeDasharray: "0,100",
              strokeDashoffset: "-25",
              autoRound: false,
              ease: "expo.in",
              duration: 0.5
            },
            0.1
          );
    
          menuTl.current.to(
            ".menu-toggle-titles",
            {
              y: -14,
              ease: "power4.inOut",
              duration: 0.4
            },
            0.5
          );
    
          menuTl.current
            .to(
              ".js-pie-middle",
              {
                rotation: 90,
                y: 8,
                x: -4,
                transformOrigin: "center",
                ease: "back.out(1.4)",
                duration: 0.5
              },
              0.6
            )
            .reverse();
        }, mobileMenu);
        return () => ctx.revert();
      }, []);

     

    • Like 2
  5. Inside  toggleMobileMenu I get error that 

    menuTl.current' is possibly 'undefined'
    const toggleMobileMenu = () => {
        menuTl.current.reversed(!menuTl.current.reversed());
      };


    But inside the useLayOutEffect I don't get any warnings. I tried to add this to the const for menuTl
     

     const menuTl = useRef<GSAPAnimation>();

    But it didn't do any difference. 

    EDIT:

    I managed to remove the errors with this code:

     

    const btn = useRef<HTMLButtonElement>(null);
     const menuTl = useRef<GSAPTimeline>(gsap.timeline());
    
      const toggleMobileMenu = () => {
        console.log("test");
        if (menuTl.current !== null) {
          console.log("test2");
          // menuTl.current.reversed(!menuTl.current.reversed());
          menuTl.current.reversed(!menuTl.current.reversed());
        }
      };
    
      useLayoutEffect(() => {
        const ctx = gsap.context(self => {
          menuTl.current = gsap.timeline({ paused: true });
          menuTl.current.to(
            ".js-mobile-overlay",
            {
              // yPercent: 170,
              y: "85vh",
              ease: "expo.inOut",
              duration: 1.1
            },
            0
          );
    
          menuTl.current
            .to(
              ".js-pie-top",
              {
                strokeDasharray: "0,100",
                autoRound: false,
                ease: "expo.in",
                duration: 0.5
              },
              0.1
            )
            .reverse();
        }, btn);
        return () => ctx.revert();
      }, []);

    But nothing happen when I click the button. I get this error below in the console. But I got the class mentioned in the code.

     

    react_devtools_backend.js:2655 GSAP target .js-mobile-overlay not found. https://greensock.com 
        at TopMenu (http://localhost:6006/components-stories-TopMenu-stories.iframe.bundle.js:370:30)
        at unboundStoryFn (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-node_modules_storybook_addon-backgrou-313dcc.iframe.bundle.js:16918:12)
        at ErrorBoundary (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-node_modules_storybook_addon-backgrou-313dcc.iframe.bundle.js:14550:5)
        at WithCallback (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-node_modules_storybook_addon-backgrou-313dcc.iframe.bundle.js:14430:23)

     

  6. 58 minutes ago, Cassie said:

    Glad you got it working, but I would suggest against using that code as it's not doing correct animation cleanup and it's using an old version of React (hence why it's working without cleanup, this is mainly important after React 18 due to strict mode)

    If you do go ahead with it, you may run into issues.  Just a little FYI so you're aware. ☺️

    Thanks for the heads up! Will see if I get it to work with the code example below. 

  7. 7 minutes ago, Rodrigo said:

    Hi,

     

    As @Cassie mentions that is a very old example. Is better to use this as a reference:

    https://stackblitz.com/edit/vitejs-vite-4jhqox

     

    This is also another option leveraging all the options GSAP Context offers to achieve the same result:

    function App() {
      const svgContainer = useRef();
      const ctx = useRef();
    
      const toggleMenuTimeline = () => {
        ctx.current.toggleMenu();
      };
    
      useLayoutEffect(() => {
        ctx.current = gsap.context((self) => {
          const menuTl = gsap
            .timeline({ paused: true })
            .to('#topBar', {
              duration: 0.2,
              x: 52,
              stroke: '#006600',
              rotation: 45,
            })
            .to('#middleBar', { duration: 0.2, alpha: 0 }, 0)
            .to(
              '#bottomBar',
              { duration: 0.2, x: 52, stroke: '#006600', rotation: -45 },
              0
            )
            .reverse();
          self.add('toggleMenu', () => {
            menuTl.reversed(!menuTl.reversed());
          });
        }, svgContainer);
        return ctx.current.revert();
      }, []);
    
      return (/*...*/);
    }

     

    Happy Tweening!

    Thanks will try this. But I had problems with current and useRef  and to have it in it's own function App(){}. before I got it to work. 

    I have the timeline directly inside of the code below, is that why it doesn't work with a function, does it have to be it's own component? 
     

    export const TopMenu: React.FC<TopMenuProps> = ({
    primaryNavLinks,
    secondaryNavLinks,
    languages
    }) => {
    export const TopMenu: React.FC<TopMenuProps> = ({
      primaryNavLinks,
      secondaryNavLinks,
      languages
    }) => { ... };


     

  8. I solved it with this code, taken from: https://codesandbox.io/s/gsap-hamburger-toggle-menu-u07i6?file=/src/App.js:1045-1073,
     

    const [tlMenu] = useState(gsap.timeline({ paused: true }));
    
      useEffect(() => {
        tlMenu.to(
          ".js-mobile-overlay",
          {
            // yPercent: 170,
            y: "85vh",
            ease: "expo.inOut",
            duration: 1.1
          },
          0
        );
    
        tlMenu.to(
          ".js-mobile-menu",
          {
            y: 0,
            ease: "expo.inOut",
            duration: 0.9
          },
          0.1
        );
    
        tlMenu.to(
          ".js-pie-top",
          {
            strokeDasharray: "0,100",
            autoRound: false,
            ease: "expo.in",
            duration: 0.5
          },
          0.1
        );
    
        tlMenu.to(
          ".js-pie-bottom",
          {
            strokeDasharray: "0,100",
            strokeDashoffset: "-25",
            autoRound: false,
            ease: "expo.in",
            duration: 0.5
          },
          0.1
        );
    
        tlMenu.to(
          ".menu-toggle-titles",
          {
            y: -14,
            ease: "power4.inOut",
            duration: 0.4
          },
          0.5
        );
    
        tlMenu
          .to(
            ".js-pie-middle",
            {
              rotation: 90,
              y: 8,
              x: -4,
              transformOrigin: "center",
              ease: "back.out(1.4)",
              duration: 0.5
            },
            0.6
          )
    
          .reverse();
      }, []);
    
      const toggleMobileMenu = () => {
        tlMenu.reversed(!tlMenu.reversed());
    
        setTopMenuVisible(!activeMobileTopMenu);
        setActiveSubLevel(-1);
        setActiveSubSubLevel(-1);
      };

    Still don't know why it works though. Shouldn't I need context to be able to use different classes and so on? 

  9. I have looked at this code https://stackblitz.com/edit/gsap-react-basic-f48716?file=src%2FApp.js and copied:
     

    const container = useRef();
      const tl = useRef();
    
      const toggleTimeline = () => {
        tl.current.reversed(!tl.current.reversed());
      };
    
      useLayoutEffect(() => {
        const ctx = gsap.context((self) => {
          const boxes = self.selector('.box');
          tl.current = gsap
            .timeline()
            .to(boxes[0], { x: 120, rotation: 360 })
            .to(boxes[1], { x: -120, rotation: -360 }, '<')
            .to(boxes[2], { y: -166 })
            .reverse();
        }, container); // <- Scope!
        return () => ctx.revert(); // <- Cleanup!
      }, []);


    and put it inside of of this:

    export const TopMenu: React.FC<TopMenuProps> = ({
      primaryNavLinks,
      secondaryNavLinks,
      languages
    }) => {
    
    ...
    };


    Inside of

    return (..);


    I have put these two on a div and a button.
     

    ref={container} 
    
    onClick={toggleTimeline}


    Doing this I get error on tl.current ('tl.current' is possibly 'undefined'.ts(18048)) and self.selector (

    Cannot invoke an object which is possibly 'undefined'.ts(2722)
    'self.selector' is possibly 'undefined'.ts(18048)

    )
    Is this because the code is inside of

    export const TopMenu: React.FC<TopMenuProps> = ({
      primaryNavLinks,
      secondaryNavLinks,
      languages
    }) => {...};

    Or what else have I missed? 

    I just want a timline that can play forward on button click and reverse itself on next click on same button. The timeline I want to use is this one, 

    See the Pen JjBgQrO?editors=0010 by Devotee007 (@Devotee007) on CodePen

  10. I have tried to set up a bit of my code stackblitz. I don't know if that's enough code? I have tried to use current in different ways but I get the error "Property 'current' does not exist on type 'void'.ts(2339)" so I have reverted back to the code seen  on the link. Can it be that current won't work when I have it inside this:

    export const TopMenu: React.FC<TopMenuProps> = ({
    primaryNavLinks,
    secondaryNavLinks,
    languages
    }) => {--};

     
    Here's the link to stackblitz: https://stackblitz.com/edit/gsap-react-basic-f48716-8mtrkg?file=src%2FApp.js,src%2Fgsap-react.tsx

     



     

  11. I got the below code to work so that the animation just play on button click, but it doesn't reverse, it plays the animation from the start every time I click the button.  So even if handleMenuClick is true or false it plays the timeline forward.

     

     
    const [isBoxVisible, setIsBoxVisible] = useState(false);
      const [menuClicked, setMenuClicked] = useState(false);
    
      const tl = gsap.timeline({ paused: true, reversed: true });
      tl.set(".box", { y: 0 });
      tl.to(".box", { y: 90, ease: "power3", duration: 2 });
    
      function handleMenuClicked() {
        setMenuClicked(prevMenuClicked => {
          console.log("before", prevMenuClicked);
          const newMenuClicked = !prevMenuClicked;
          console.log("after", newMenuClicked);
          return newMenuClicked;
        });
      }
    
      useEffect(() => {
        setIsBoxVisible(true);
      }, []);
    
      useEffect(() => {
        console.log("IF: " + menuClicked);
        tl.progress() === 0 ? tl.play() : tl.reverse();
      }, [menuClicked, tl]);

     

  12. I have a React component for a top menu. I have animated the menu with CSS (Tailwind), but I want, of course, use GSAP instead. I have just started and this is the first time I use React, so a bit of a newbie. Below is the code that I have for the GSAP animation. The thing that happens in then I click on the buttons that starts CSS-animations the GSAP animation below fires as well. The page doesn't reload or anything. Is there something in the below code that I have forgotten to use? 


     

    export const TopMenu: React.FC<TopMenuProps> = ({
      primaryNavLinks,
      secondaryNavLinks,
      languages
    }) => {
      // GSAP CODE
      const component = useRef(null);
    
      useEffect(() => {
        let ctx = gsap.context(() => {
          console.log("GSAP");
          gsap.from(".box", { opacity: 0, y: -90, ease: "power3", duration: 2 });
        }, component);
      });
      //END GSAP CODE

     

  13. @mvaneijgen, this is the updated codepen I changed this:

     

    stroke-dashoffset from 0 to -125

    <circle class="bottom" cx="50%" cy="50%" r="15.9" stroke="pink" stroke-dasharray="25 100" stroke-dashoffset="-125"></circle>


    After that the flickering stopped. In the video file in previous post you can see the "flickering". When I just did the animation with CSS it was smooth.

    After changing from 0 to -125 the ease on the animation seem to happen backwards on the pink area. See video file in this post. Both the green and pink are has ease:"back.in" when I recorded it.

    Thank you for your tip about the code, I will updated. :)

     

    • Like 1
  14. Solved it by changing stroke-dashoffset from 0 to -125

     

    <circle class="bottom" cx="50%" cy="50%" r="15.9" stroke="pink" stroke-dasharray="25 100" stroke-dashoffset="-125"></circle>

     

    And then this GSAP code.

    const tl = gsap.timeline({ paused: true, reversed: true})
    tl.to('.top', {strokeDasharray: "0,100", duration:.3}, 0)
    tl.to('.bottom', {strokeDasharray: "0,100", duration:.3}, 0)
    tl.to('.icon', {x:"7.5rem", duration:.3}, .1)

    const playBtn = document.getElementById('icon')

    playBtn.addEventListener('click', () => {
      tl.reversed() ? tl.play() : tl.reverse()
    })

     

    //Devotee007

  15. Hi,

    I have this code for a CSS animation of a pie chart. It works fine. 
    .icon:hover .bottom  {
      stroke-dasharray: 0 100;
      stroke-dashoffset: -25;
    }

    But when I do this with GSAP - tl.to('.bottom', {strokeDasharray: "0,100", strokeDashoffset: "-25", dutation:.3}, 0)  the animation stagger. 

    What am I doing wrong? using stroke-dashoffset: -25; was the only solution I found to reverse the animation of the pink pie part. Is there another solution?

    //Devotee007

    See the Pen JjBgQrO by Devotee007 (@Devotee007) on CodePen

×
×
  • Create New...