Jump to content
Search Community

React Scalar/Number Transition using GSAP

Andrew Harris test
Moderator Tag

Recommended Posts

Hi there!

I would like to add a scalar tween to a component in React using GSAP, the component is a functional component.

I've whipped up a quick example of how i think that could be implemented in React using GSAP in the attached codepen. (Type in some number values into the input and watch GSAP tween the number below the input)

 

It's a bit dirty as i need to add a global object to the window on the first mount of the component, so that GSAP has an object it can freely mutate without React resetting it on each render.

Is there are better way of allowing GSAP to perform a scalar transition within React?

Thanks for any help you can give!
 

See the Pen mddKRmE by andrewmumblebee (@andrewmumblebee) on CodePen

Link to comment
Share on other sites

Hi Andrew,

 

Just to clarify, you just need an object to update one or more values in it, and that is not related to the component's state? I'm a little lost in what exactly you want to achieve here.

 

Keep in mind that using a functional component and the Hooks API you're kind of forced to use the useState() hook as well in order to update the number in the DOM view. Also keep in mind that React has become more and more efficient in terms of what is actually updated and re-rendered with time. While manipulating the DOM in the useEffect hook certainly works is not the react-way of doing things (actually Dan Abramov could suffer a stroke if He sees that part of your code :D).

 

If I was you I'd stick with using useState and useEffect to update the value and perhaps create a specific component just for showing the value so the only element that is actually re-rendered is the one being affected by that value, but again I'm not entirely clear of what you're doing.

 

Happy Tweening!!!

  • Like 4
Link to comment
Share on other sites

Hi Rodrigo,

Thanks for the reply! Haha, I wouldn't want our lord and saviour Dan Abramov to suffer a stroke ?

Sorry for not being clear, i want to have a component that displays a number value that is animated up or down whenever the value changes. My actual use case is for a pricing calculator, whereby the price will animate up and down whenever a user changes parameters on other components. So yes the object values are related to the component's state, the object is merely there so GSAP can tween the value between the previous state and current state.
Does that make sense?

I'd done this before when i was working with JQuery & GSAP, i used a similar technique of having an object in a closure that GSAP would tween the value of and then apply the value on each update to the DOM element. Same technique as the below thread.


So that's what i thought would be easiest to use again, although yes it's not the React way of doing things. As now GSAP is in control of the rendered value.

 

I'm also not sure how you'd get GSAP to tween a React hook state value, as i thought we shouldn't ever mutate the state value directly, so would need GSAP to call a setter method.

Thanks again for helping me out! Hope i'm not being confusing.

 

Link to comment
Share on other sites

This seems to be doing what you want, if I understood correctly:

 

https://codesandbox.io/s/gsap-react-number-animation-hooks-xpyq4

 

The main idea is to use a proxy object so GSAP has something to update the value and not make it depend on some state property. Since you're most likely using some bundling tool this will be inside a closure so that particular object will remain inside that particular scope. Then in the onUpdate callback you can update the state of the component showing the number so it works independently of the component that actually creates the number.

 

Hopefully this helps.

 

Happy Tweening!!!

  • Like 5
Link to comment
Share on other sites

  • 2 years later...
const AnimatedNumber = ({ delay, displayValue, fontSize }) => {
  
  const ref = useRef()
  const foo = useRef({ bar: 0 })

  useEffect(() => {
    gsap.to(foo.current, {
      bar: Math.round(displayValue),
      duration: 1,      
      ease: 'power2.out',
      delay: delay,
      onUpdate: function () {        
        ref.current.innerText = Math.round(foo.current.bar) + '%'
      },
    })
  })

  return (
    <h4 ref={ref} className="font-weight-bold " style={{ fontSize: fontSize }}>
      <span>this will be overridden</span>
    </h4>
  )
}

Thanks for the example @Andrew Harris.


I got better performance by manipulating the dom manually and avoiding using react 's usestate. As i understand it - the useState hook might not run for every update, so your animation can end up looking janky. 

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...