Jump to content
GreenSock

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

Issue with TweenMax on ReactJS Hooks

Recommended Posts

Hi everyone,

I'm working on a projet where I have a menu, and a side-menu.
Every thing is fine: when i click on the menu button the side menu opens, and when i click again it get back to close state.
But if I click to fast the side menu closes but the text inside doesn't disapear, any idea on why please ? :)

(I can't reproduce on codepen so I guess the code here and the two screen would help ^^" )
Screen 1: side menu is closed
Screen 2: side menu is open
Screen 3: side meni is closed but text inside is still visible

My GSAP code:
 

const handleAnim = () => {
        let sideMenuBackground = document.querySelector(".sideMenu__background");
        let sideMenu = document.querySelector(".sideMenu");

        if (menuCheckbox) {
            TweenMax.from(sideMenuBackground, 0, {
                width: "0px",
                ease: Power1.easeIn
            })

            TweenMax.to(sideMenuBackground, 0.3, {
                width: "324px"
            })

            TweenMax.from(sideMenu, {
                display: "none",
                opacity: "0",
                ease: Power0.easeNone
            })

            TweenMax.to(sideMenu, 0.3, {
                display: "block",
                opacity: "1",
                delay: 0.4
            })

        } else {
            TweenMax.to(sideMenu, {
                display: "none",
                opacity: "0",
                ease: Power0.easeNone
            })

            TweenMax.to(sideMenuBackground, 0.1, {
                width: "0",
                delay: 0.2
            })
        }
    }


The "handleAnim" function is called in menu burger button and icons button: 
 

<nav className={`navList ${menuCheckbox && "navList__isOpen"}`}>
    <div className={menuCheckbox ? "menuBurger__nav menuBurger__cross" : "menuBurger__nav"}>
        <input
            type="checkbox"
            onClick={() => {
                handleCheckbox();
            }}
        />

        <span className="top"></span>
        <span className="middle"></span>
        <span className="bottom"></span>
    </div>

    <ul>
        <li>
            <button onClick={() => {
                handleCheckbox();
            }}>
                <i className="fal fa-folders"></i>
            </button>
        </li>

        <li>
            <button onClick={() => {
                handleCheckbox();
            }}>
                <i className="fal fa-balance-scale"></i>
            </button>
        </li>

        <li>
            <button onClick={() => {
                handleCheckbox();
            }}>
                <i className="fal fa-receipt"></i>
            </button>
        </li>
    </ul>
</nav>



 

Screenshot_2020-06-10__1.png

Screenshot_2020-06-10__2.png

Screenshot_2020-06-10__3.png

Link to comment
Share on other sites

It looks to me like your issue is caused by your delayed tweens still continuing to run once you click again.
 

It also appears that you should be using a .fromTo() tween (instead of setting a .from with a 0 duration followed by a .to).

It may be best to set each action as a timeline with a specified variable, and kill that when the other is activated.

What version of GSAP are you using? You're missing the time value from your first tween in the else statement, and this could cause issues if you are using an old version of gsap, your syntax is also from v2.x instead of the current version 3. 

 

You may also consider just setting a timeline for the animation as a whole, and reversing it with a faster timescale when the 'else' is triggered

 

  • Like 2
Link to comment
Share on other sites

Some info on converting from v2 to v3:

 

Link to comment
Share on other sites

15 hours ago, elegantseagulls said:

It looks to me like your issue is caused by your delayed tweens still continuing to run once you click again.
 

It also appears that you should be using a .fromTo() tween (instead of setting a .from with a 0 duration followed by a .to).

It may be best to set each action as a timeline with a specified variable, and kill that when the other is activated.

What version of GSAP are you using? You're missing the time value from your first tween in the else statement, and this could cause issues if you are using an old version of gsap, your syntax is also from v2.x instead of the current version 3. 

 

You may also consider just setting a timeline for the animation as a whole, and reversing it with a faster timescale when the 'else' is triggered

 

Hi, thanks for your answer :)

In fact i'm already on v3
 

"gsap""^3.2.6",


Thing is i tried to use fromTo on Reactjs but I couldn't find a way to make it work.
There is not really a "how to use it" with React except this page :


As you can see it's on V2, and no example with fromTo ^^"
I tried several youtube guide, but they re alll doing this too.
I'm kinda lost :(

Link to comment
Share on other sites

There might not be too much information on GSAP + React but I know of some courses outside of the GreenSock website that talk about it in more depth. I'm also aware of another one being made right now.


But to learn about .fromTo()s you don't need to look at something React specific. Just look at the docs! Or check out the Getting Started article. React is just a framework - most of what you need to learn in terms of GSAP you can learn from our many learning resources :) 

Link to comment
Share on other sites

4 minutes ago, ZachSaucier said:

There might not be too much information on GSAP + React but I know of some courses outside of the GreenSock website that talk about it in more depth. I'm also aware of another one being made right now.


But to learn about .fromTo()s you don't need to look at something React specific. Just look at the docs! Or check out the Getting Started article. React is just a framework - most of what you need to learn in terms of GSAP you can learn from our many learning resources :) 


Oh I can see now that I m not so clear, to be more precise I do know fromTo, but in React it's different, seems that I need to import fromTo like this :

import { TweenMaxfromToPower0Power1 } from "gsap";

Since I did not need to import éfrom" or "to" I though fromTo would works the same way x)

Gonna read the doc for fromTo in V3 !
Thx a lot ! :)

 

Link to comment
Share on other sites

2 minutes ago, Guutak said:

seems that I need to import fromTo like this :

import { TweenMaxfromToPower0Power1 } from "gsap";

Since I did not need to import éfrom" or "to" I though fromTo would works the same way x)

There's no need to import any of that stuff. All you need is import { gsap } from "gsap"; like the installation docs cover. Importing fromTo is invalid no matter what version of GSAP you use.

  • Like 3
Link to comment
Share on other sites

Definitely check out the docs on the V3 Syntax changes too. Particularly: ease (now strings), duration (now defined inside the object), and no more need to use TweenMax (everything is just gsap eg: gsap.fromTo(el, { x:0 }, {duration: 0.2, x: 100, ease: 'none'})).

 

  • Like 3
Link to comment
Share on other sites

44 minutes ago, elegantseagulls said:

Definitely check out the docs on the V3 Syntax changes too. Particularly: ease (now strings), duration (now defined inside the object), and no more need to use TweenMax (everything is just gsap eg: gsap.fromTo(el, { x:0 }, {duration: 0.2, x: 100, ease: 'none'})).

 


Yep i'm on it :)

const handleAnim = () => {
        let sideMenuBackground = document.querySelector(".sideMenu__background");
        let sideMenu = document.querySelector(".sideMenu");
 
        if (menuCheckbox{
            gsap.fromTo(sideMenuBackground,
                            {width: "0px"},
                            {width: "324px", duration: 0.2}
                        )
 
            gsap.fromTo(sideMenu,
                            {display: "none", opacity: 0},
                            {display: "block", opacity: 1, duration: 0.2, delay: 0.2}
                        )
        } else {
            gsap.to(sideMenu,
                            {display: "none", opacity: 0, duration: 0.1}
                        )
 
            gsap.to(sideMenuBackground,
                            {width: "0px", duration: 0.2, delay: 0.1}
                        )
        }
    }


Still have the bug tho but i'm making progress :)

Link to comment
Share on other sites

8 minutes ago, Guutak said:

Stil have the bug

As mentioned in my first response, I think the bug is due to the tween still running (not being paused or killed) after the close is clicked, so the delay is still being animated. Have you tried setting the tweens as a variable and killing them so that the delay isn't trying to run after the close is clicked?

 

Something like this:

const sideMenuBackground = document.querySelector(".sideMenu__background");
const sideMenu = document.querySelector(".sideMenu");
const openTL = gsap.timeline({paused: true})
openTL
  .fromTo(sideMenuBackground,
    {width: "0px"},
    {width: "324px", duration: 0.2}
  )
  .fromTo(sideMenu,
    {display: "none", opacity: 0},
    {display: "block", opacity: 1, duration: 0.2, delay: 0.2},
    0		
  );

const closeTL = gsap.timeline({paused: true})
closeTL
  .fromTo(sideMenu,
    {display: "block", opacity: 1},
    {display: "none", opacity: 0, duration: 0.1}
  )
  .fromTo(sideMenuBackground,
    {width: "324px"},
    {width: "0px", duration: 0.2, delay: 0.1},
    0
  )

const handleAnim = () => {
  if (menuCheckbox) {
    closeTL.pause();
    openTL.play(0);
  } else {
    openTL.pause();
    closeTL.play(0);      
  }
}

If you wanted to define everything in the click function, you could then use the kill function instead of pause, then you wouldn't need to set the play() at play(0), but would be setting new tweens/timelines (as you are currently) with every click.

 

  • Like 4
Link to comment
Share on other sites

2 minutes ago, elegantseagulls said:

or just use this to stop conflicting tweens: https://greensock.com/docs/v3/GSAP/gsap.killTweensOf()


Ok i tried this one, and it makes the job perfectly !
I'm not really a JS dev front (more HTML/CSS with a little bit of javascript), this is why i m kinda didn't get how to do your first solution ^^"
(The first one does the job to tho)

Anw, thanks  ! :)

Link to comment
Share on other sites

3 hours ago, elegantseagulls said:

or just use this to stop conflicting tweens: https://greensock.com/docs/v3/GSAP/gsap.killTweensOf()

Yep, totally legit or if you want to have GSAP automatically kill all other tweens of the same target when creating a new one, just add overwrite: true to your new tween and BOOM they're nuked. 👍

  • Like 2
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.
×