Andrew Harris Posted November 8, 2019 Share Posted November 8, 2019 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 More sharing options...
ZachSaucier Posted November 8, 2019 Share Posted November 8, 2019 Hey Andrew and welcome. As this is a React question, most of our regulars aren't as skilled and may not be able to help too much. Perhaps our resident expert @Rodrigo will stop by and give you some pointers Happy tweening. 1 Link to comment Share on other sites More sharing options...
Rodrigo Posted November 8, 2019 Share Posted November 8, 2019 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 ). 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!!! 4 Link to comment Share on other sites More sharing options...
Andrew Harris Posted November 10, 2019 Author Share Posted November 10, 2019 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 More sharing options...
Rodrigo Posted November 11, 2019 Share Posted November 11, 2019 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!!! 5 Link to comment Share on other sites More sharing options...
ddennis Posted December 5, 2021 Share Posted December 5, 2021 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now