Jump to content
Search Community

Button Hover Animation with React all Choppy and Irresponsive.

Jae P test
Moderator Tag

Recommended Posts

Hello,

 

I've recently began using gsap. I was able to do everything fine until I found out I was unable to set a transfrom timer on CSS due to its conflict with gsap timer. Therefore, I've been trying to create a button hover animation by using gsap on reactjs. However, it is very weird and choppy. I cannot explain it. I will include a video and my code.

I am using onMouseEnter and onMouseLeave as event listeners on my JSX file and passing a function over with the gsap animation code inside of it.  I'm not really sure if it's the onMouseEnter/onMouseLeave indicators that's causing the choppiness. I've also tried onMouseOver/onMouseOut, but with same results.

 

1. useRef to target DOM elements

let team = useRef(null)
 let teamLine = useRef(null)

 

2. functions used to set animations on call

function mouseOver(evt) {
    tl.fromTo(team, 2.5, { x: "0" }, { x: "-30px"ease: Power2.ease }, 0)
      .to(teamLine, 2.5, { x: "100px"opacity: 1ease: Power2.ease}, 0)
  }
 
  function mouseLeave(evt) {
    tl.fromTo(team, 2, { x: "-30px" }, { x: "0"ease: Power2.ease },0)
      .fromTo(teamLine, 2, { x: "100px"opacity: 1}, { x: "0"opacity: 0ease: Power2.ease },0)

 

3. HTML element in JSX

<div
            className='team-container' 
            onMouseEnter={mouseOver} 
            onMouseLeave={mouseLeave}>
              <Link  
                class='team' 
                to='/the-team' 
                exact style={textDecoration: 'none' }}>
                <p ref={el => team = el}>Meet the Team</p>
              </Link>
            <div 
              className='team-line' ref={el => teamLine = el}>
            </div>
   </div>

 

4. SASS

.team {
          font-family: "Work Sans"sans-serif;
          color: white;
          width: 150px;
          height: 20px;
          letter-spacing: 0.1rem;
          position: relative;
          cursor: pointer;
          z-index: 5;
        }
 
        .team-line {
          position: absolute;
          height: 1px;
          top: 50%;
          width: 50px;
          background: white;
          opacity: 0;
        }

 

 

What I am expecting:

     'Meet the Team' text slides left of 30px as the invisible bar behind it slides to the right 100px while fading in

 

Result:

Link to comment
Share on other sites

Hey Jae and welcome to the GreenSock forums! 

 

You should definitely be using the enter and leave events, not over because over would fire it a lot of times.

 

I'm guessing that this issue is related to you using a timeline and setting the start time of each tween to 0 each time. If the timeline's playhead is already past the duration of the tween, it will jump to that state. There's no reason to use a timeline there anyway. 

 

You should just use regular tweens instead:

gsap.fromTo(team, { x: 0 }, { duration: 2.5, x: -30, ease: "power2" })
gsap.to(teamLine, { duration: 2.5, x: 100, opacity: 1, ease: "power2"})

Notice that I used x: -30 instead of x: "-30px". I also moved the duration to inside of the vars parameter and used the string form of the ease as is recommended in GSAP 3. 

 

Alternatively you could create the timeline(s) beforehand (i.e. outside of the event listener functions) including the tweens on them and then use control functions like .play() or .reverse() inside of the event listener functions.

  • Like 2
Link to comment
Share on other sites

Hey Zach,

 

Thank you so much for your help and for the insight about GSAP 3 convention. The button is good now with a little bit of tweaks.

As for the alternative, are there any performance differences between the solution you've provided and the alternative method you've mentioned? If there aren't any,  which is more conventional?

 

Thanks for your time :)

 

-Jae

Link to comment
Share on other sites

You almost certainly wouldn't notice a performance difference in practice but the alternative approach that I suggested of creating the timelines and tweens beforehand and controlling them in your event listeners is technically more performant. 

 

As for convention it's hard to say. We recommend creating things beforehand if you're able to but it's not bad to do it with just tweens. They actually have subtly different effects (the tweens, unless you do your own calculations, will have a set duration whereas if you use .play() and reverse() on a timeline that was created before it will only do the remainder of the time if the state is toggled mid animation). 

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.
×
×
  • Create New...