Jump to content
GreenSock

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

[SOLVED] Is this the right approach for toggling a menu button?

Recommended Posts

https://codesandbox.io/s/sad-maxwell-2b7vv?fontsize=14

 

Edit: For clarification, this needs to use React hooks.

 

I have it transforming from = to x and vice versa, however, I had to hard code the reverse animation because I couldn't seem to get it to work by using the reverse or reveresed methods like shown below.


 

if (isMenuOpen) timeline.play()

else (timeline.reversed(true).play()

 

See the Pen by s (@s) on CodePen

Link to comment
Share on other sites

Hi @HackGibson :)

 

Welcome to the forum.

 

Here's a basic toggle to play/reverse a timeline.

 

See the Pen WqKyye by PointC (@PointC) on CodePen

 

Hopefully that helps. Happy tweening and welcome aboard.

:)

 

  • Like 2
Link to comment
Share on other sites

Is there an example using react hooks?

Link to comment
Share on other sites

React hooks is supposed to be an improvement? I don't get it. ?‍♂️

 

The way you have it, you're adding new animations to the timeline on every click. Create it once.

 

See the Pen agjKrV by osublake (@osublake) on CodePen

 

 

Also, don't set transform origin with CSS. It's doesn't work the same in every browser.

 

  • Like 5
Link to comment
Share on other sites

I didn't even see that you were using React. When I first looked at your question it had a broken CodePen link. I guess I should have refreshed. ;)

 

I see Blake is on the case and we can probably summon @Rodrigo too.

 

kkesqWD.jpg

 

They'll probably get you you fixed up. Happy tweening.

  • Haha 1
Link to comment
Share on other sites

2 minutes ago, HackGibson said:

Is there an example using react with hooks?


No.

Link to comment
Share on other sites

11 minutes ago, HackGibson said:

Is there an example using react hooks?

 

The old way would be pretty straightforward, similar to some of the demos on this page.

https://greensock.com/react

 

I just don't completely understand how useEffect works.

Link to comment
Share on other sites

Guys I really appreciate the replies. Prior to discovering GSAP I was learning to animate with React-Spring which is a lot different than GSAP. The project I'm working on requires me to use React Hooks. In this specific case the animation needs to be controlled via a prop passed to it. I was able to get it working as shown below. @OSUblake is this efficient? 

 

https://codesandbox.io/embed/runtime-waterfall-efhpl?fontsize=14

 

 

Link to comment
Share on other sites

17 minutes ago, HackGibson said:

The project I'm working on requires me to use React Hooks. 

 

That's understandable. I've known about hooks for quite sometime, I just haven't gotten my hands dirty with them yet, so it was a little confusing about how to set stuff up.

 

I'm sure this is in React's docs, but can you quickly explain how useEffect works? Why is the first call like componentDidMount and the second call is like componentDidUpdate?

 

Seeing how you did that, the demo I made above would look like this. There's really no difference besides being a little shorter.

 

// componentDidMount
React.useEffect(() => {
  TweenLite.set([topLine.current, botLine.current], {
    transformOrigin: "50% 50%"
  });
  setTimeline(
    timeline
      .to(topLine.current, 0.1, { y: 6 }, 0)
      .to(botLine.current, 0.1, { y: -6 }, 0)
      .to(topLine.current, 0.1, { rotation: 45 }, 0.2)
      .to(botLine.current, 0.1, { rotation: -45 }, 0.2)
      .reverse()
    );
}, [timeline]);

// componentDidUpdate
React.useEffect(() => {
  timeline.reversed(!isMenuOpen)
}, [isMenuOpen, timeline]);

 

 

  • Like 2
Link to comment
Share on other sites

57 minutes ago, OSUblake said:

I'm sure this is in React's docs, but can you quickly explain how useEffect works? Why is the first call like componentDidMount and the second call is like componentDidUpdate?

 

First I should say the only reason timeline is in the 2nd argument array for useEffect is because codesandbox's linter suggests it, but it's not required. I've actually changed it to an empty array like the React docs suggest.

 

If there is no array for that 2nd argument, the useEffect method runs on every re-render. If there is an empty array, it runs on the first render only, the same behavior as componentDidMount. If there is a prop in that array, it will only run on a re-render if the prop's value changed, which is the same behavior as componentDidUpdate. And lastly, if you return a function it acts as componentWillUnMount. Check the console.log lines below.

 

  // componentDidMount
  React.useEffect(() => {
    console.log("useEffect 1: this executes only once.")
    TweenLite.set([top.current, bot.current], { transformOrigin: "50% 50%" })
    setTimeline(
      timeline
        .to(top.current, 0.1, { y: 6 }, 0)
        .to(bot.current, 0.1, { y: -6 }, 0)
        .to(top.current, 0.1, { rotation: 45 }, 0.2)
        .to(bot.current, 0.1, { rotation: -45 }, 0.2)
        .reverse()
    )
    return () => {
      // componentWillUnmount
    }
  }, [])

  // componentDidUpdate
  React.useEffect(() => {
    console.log(
      "useEffect 2: this executes on every click because isMenuOpen changes on every click"
    )
    timeline.reversed(!isMenuOpen)
  }, [isMenuOpen])

 

Thanks for your help! ❤️

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Thanks! That makes much more sense now.

  • Like 2
Link to comment
Share on other sites

16 hours ago, OSUblake said:

Also, don't set transform origin with CSS. It's doesn't work the same in every browser.

 

I should clarify that I only meant for SVG elements. 

 

Setting the transform origin with CSS for HTML element won't cause any problems.

  • Like 4
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×