Jump to content
Search Community

GreenSock ReactJS components needed

BowserKingKoopa test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I'm currently using GSAP in ReactJS (via https://github.com/hzdg/gsap-react-plugin). But it's difficult because it's an awkward mix of functional React code and imperative GSAP code. And you have to jump through hoops to make sure GSAP doesn't interfere with the React rendering. 

 

We desperately need something like this:

 

https://fabric.io/blog/introducing-the-velocityreact-library

 

 

-Ryan

Link to comment
Share on other sites

Hi Ryan,

 

As far as I can see the only issue I could spot in the GSAP-React plugin is using the state object of the component and then render the component once again.

 

For static components, that is components that doesn't have any data or setState updates, I would use the componentDidMount() method to create the GSAP instances, because at that point the elements are rendered in the DOM and you can access them through other libraries, such as GSAP, jQuery, etc. For dynamic components I would use the componentDidUpdate() method.

 

Something like this:

var yourComponent = React.createClass({

  // static components
  componentDidMount : function(){
    TweenLite.to(target, 1, {x:100, y:100});
  },

  // dynamic components
  componentDidUpdate : function(){
    TweenLite.to(target, 1, {x:100, y:100});
  },

  render : function(){
    // render code here
  }

});

Finally, if you need to update some data in the component, based on the changes made by GSAP, you can use any GSAP callback to call the setState method and update the component's state object data.

 

Hopefully this helps a bit.

  • Like 3
Link to comment
Share on other sites

Thanks for the info/suggestions, Rodrigo.

 

Ryan, it would be super helpful if you had a reduced test case that shows a key problem that you're running into inside of React when using GSAP. That'd help shed light on exactly what's going on under the hood and how we might be able to help. I'm not a React guy, so any hints you could offer would be appreciated. Again, that reduced test case would be amazing. 

Link to comment
Share on other sites

The problem is fundamental. Imperative GSAP code doesn't fit well with declarative React code. The problem isn't specific to GSAP. React does not have a good animation story at the moment. This is something I hope GSAP might address in the future. The blog post I linked describes the problem well:

 

"React and animation don’t actually play well together at first. There’s an impedance mis-match: React’s power stems from abstracting away the state transitions in your UIs (it does them quickly and correctly, enabling the declarative paradigm we’ve come to love), while animations live entirely within those state transitions."

 

and

 

"To integrate smoothly with React’s declarative nature, we’ll need our animation behavior to be fully described by the output of our render methods: a desired end state."

 

https://fabric.io/blog/introducing-the-velocityreact-library

 

Their solution was a set of React components that let them create animations in a React friendly way. Something like that for GSAP would be amazing. GSAP should embrace React.

  • Like 1
Link to comment
Share on other sites

Hey Ryan,

 

I see the predicament. Unfortunately GSAP has to work out of the box and play nice with every possible scenario. This is on Jack's or other developers' court now, as to develop a GSAP plugin that jumps right into React and do things the React way.

 

I've done juts a few things  in React with GSAP and the approach from my first post has worked fine so far.

 

On the other hand, today's web and UI's are generally animated and interactive, so developers of this type of technology should also be held responsible for creating this frameworks in a way that doesn't present this type of situations when the end developer is trapped in this type of predicaments, since GSAP is one of many JS animation libraries that exists now a days.

 

Perhaps for now using CSS transitions could be the best option.

 

Sorry that I can't be more helpful about it.

Link to comment
Share on other sites

Is there any way somebody with even a little React experience could provide a reduced test case in codepen (or whatever) that demonstrates the problem that we need to overcome? In other words, if you use React's getDOMNode() to find the correct target and then animate that directly with GSAP, what do I need to do in order to break it?

 

Is React literally trashing the node that's animating at some point (when render() is called), and then swapping in a new node, thus GSAP is targeting the wrong thing at that point (nor more animation)? I just need something that shows the issue so that I can dig in and fix it (or try at least). 

 

I'm hearing lots of talk about React, how it abstracts away the DOM updates, etc., how it's not well-suited to any animation library except ones that are built specifically for it, but I'm having a very tough time finding anyone who can actually show me a demo with it broken using GSAP. I don't doubt that it's breaking - I just really need something to explore and tinker with. I've already gotten several things to animate fine in React using GSAP and the getDOMNode() method but I'm sure I'm missing some obvious stuff. I'm a total React newbie. 

 

Help? 

Link to comment
Share on other sites

I don't know enough about React, so I can't help out with a demo, but the React GSAP Enhancer solves the mutation problem by saving the attributes after every render.

 

After reading through the OP's comments a couple of times, I think he's looking more for a way to create animations in a declarative way. The Angular team experimented with that idea. Here's a couple of their demos.

See the Pen jEVyjr?editors=1000 by ThomasBurleson (@ThomasBurleson) on CodePen

See the Pen KwNoNP?editors=1000 by ThomasBurleson (@ThomasBurleson) on CodePen

 

It works. But it's also very limiting. Imperative code gives you much more control over your animations. 

  • Like 1
Link to comment
Share on other sites

The problem is fundamental. Imperative GSAP code doesn't fit well with declarative React code. The problem isn't specific to GSAP. React does not have a good animation story at the moment. This is something I hope GSAP might address in the future. The blog post I linked describes the problem well:

 

"React and animation don’t actually play well together at first. There’s an impedance mis-match: React’s power stems from abstracting away the state transitions in your UIs (it does them quickly and correctly, enabling the declarative paradigm we’ve come to love), while animations live entirely within those state transitions."

 

and

 

"To integrate smoothly with React’s declarative nature, we’ll need our animation behavior to be fully described by the output of our render methods: a desired end state."

 

https://fabric.io/blog/introducing-the-velocityreact-library

 

Their solution was a set of React components that let them create animations in a React friendly way. Something like that for GSAP would be amazing. GSAP should embrace React.

 

agree with you 100%, given the immense popularity of reactjs, it would be very helpful.

 

Btw, have you check out this post:

http://greensock.com/forums/topic/13970-wrote-an-article-that-demos-how-to-use-gsap-with-react/

Link to comment
Share on other sites

Yes, I'd love to help ensure that it's simple to use GSAP with React. Frankly, I think React should also put forth some effort to make it easier to integrate animations & libraries because in this equation it sure seems like React is the thing that's making it very difficult (GSAP can animate any property of any object and is totally rendering-layer agnostic, so it's a bit baffling to understand why it wouldn't already be simple to drop in GSAP as-is). 

 

Anyway, I've asked a bunch of people to show me a reduced test case that demonstrates the core issue, where something breaks with GSAP animating in React. Not a single person has responded to the challenge. Nobody. Crickets chirping. Some of these people are pretty experienced with React (unlike me) and also big GSAP fans. So I must admit that I'm really struggling to find something to fix, or at least make sure I'm understanding the crux of the issue fully. I hear lots of theoretical talk, about the rendering cycle and DOM mutation, but it'd really really help if I had an actual example that's breaking so that I can make sure I get that particular use case working. 

 

Any takers? Pretty please? A simple codepen (or whatever)? 

  • Like 1
Link to comment
Share on other sites

Nothing's really breaking. There's nothing to really fix. (Except your entire way of thinking. Ha! React!).

 

GSAP and React just don't play together well. This blog post does a good job of describing the problem as well as proposing a good example of a solution: https://fabric.io/blog/introducing-the-velocityreact-library

 

Hooking into React lifecycle methods to fire off GSAP calls is a hack. What the React developer really wants to do is describe the animation declaratively in the Render method using React components. The linked blog post shows a possible way of doing that that looks like a good start to me. It's more like CSS animations where you say 'when this property is animated do it like this'.

 

Think of it as us wanting GSAP in another language, the language being React Components.

 

Look into React. The Kool-Aid tastes great! Read that blog post. It presents a nice idea of what animation components might look like in a React style.

Link to comment
Share on other sites

Ha. "nothing to fix....except your entire way of thinking!" 

 

You said "GSAP and React just don't play together well" and that's exactly what I'm fuzzy on. Why *exactly* do you say they don't play well together? 

 

I read the blog post a few times. I'm still unclear about a real solution, though. Building a React component that abstracts away the GSAP code sounds like what's being requested, but I have a bunch of concerns:

  1. People often say they want to use React because of its performance, but from what I can tell, the way animations would have to be done in React is quite the opposite - it'd be much more expensive. We're not "allowed" to set properties directly on the animated element (fast); instead, we've gotta make everything run through React (introducing a middle-man that slows things down). And/or if we've gotta hook into the React lifecycle methods, each time a render() happens we'd have to revert all the stuff that the tween was doing, record the progress of that tween, let React do its render, create a new tween and seek() to that original position that the in-progress tween was at. This is *NOT* good for performance. Why are we doing this again? What are the benefits? Isn't one of the primary goals **performance**? 
  2. Whenever I've seen "declarative" animation done, it tends to get extremely verbose for anything but the most simple of animations. It also doesn't lend itself very well to "reactive" interfaces, where things are dynamic and based on user interaction. Is it a good idea to head down this path of making a declarative wrapper for GSAP in React? That's basically what is being requested, right? 
  3. Is React stable? From what I gather, it's a bit of a moving target, and considered "beta" at this point, right? Might we jump through a bunch of hoops to tie things into lifecycle methods that then change in a few months? 

Would you mind writing some pseudo code that shows how you'd ideally like to work with GSAP in React, like as a component? Maybe that'd help me understand better. 

 

Oh, and I hope I'm not coming off as argumentative or negative - I don't mean it that way. I'm honestly trying to wrap my head around precisely what the problems are, WHY they are perceived as problems, what *exactly* is being requested and how to deliver that. I could easily slap together a component based loosely on the one in that article you mentioned, but I don't want to do that hastily without comprehending core issues. Maybe there's a much better solution we could recommend. Or not :)

  • Like 2
Link to comment
Share on other sites

  • 3 weeks later...

  1. People often say they want to use React because of its performance, but from what I can tell, the way animations would have to be done in React is quite the opposite - it'd be much more expensive. We're not "allowed" to set properties directly on the animated element (fast); instead, we've gotta make everything run through React (introducing a middle-man that slows things down). And/or if we've gotta hook into the React lifecycle methods, each time a render() happens we'd have to revert all the stuff that the tween was doing, record the progress of that tween, let React do its render, create a new tween and seek() to that original position that the in-progress tween was at. This is *NOT* good for performance. Why are we doing this again? What are the benefits? Isn't one of the primary goals **performance**? 

 

In my opinion react is popular right now because it solves some of the problems of client applications in a different way, and on some specific situations this can be beneficial.

A lot of us who use GSAP all we care about is performance and having control of what out application does, that's why we end up just using vanilla javascript (or maybe es6), structuring our application in a mv pattern with no framework or a very minimal one (backbone, etc).

 

If you want the best performance and control over your animations and application behavior react is not the best choice.

 

Link to comment
Share on other sites

The thing about React is not performance gains. Sometimes you get some because it knows all the hacks and tricks and minutiae of DOM manipulation (as does GSAP). But that's not the thing. The thing is Immediate Mode (yay!) vs Retained Mode (yuck). React lets you code as if the Retained Mode DOM was, in fact, Immediate Mode. Immediate Mode is such a big win I'd trade performance for it. I'd trade GSAP for it (though I don't want to). I'd trade almost anything for it. It's that big of a win. It's the proper API for building a UI.

 

The performance hit for putting GSAP on top of React hasn't proven to be noticeable in my current game project. I'm using https://github.com/hzdg/gsap-react-plugin which pipes all my GSAP animations through React's setState mechanism. I've suffered no noticeable performance hit for doing so.  (It might not even be slower. Probably depends on who is better at DOM manipulation, GSAP or React). 

 

So I'm quite happily using GSAP with React. I'd be happier if GSAP had a React Component API though, which is what this post was about.

  • Like 1
Link to comment
Share on other sites

Hi and welcome to the GreenSock forums.

 

Thanks for your input in this matter. All opinions are welcome.

 

As you mention react has come to solve a specific issue or fill a gap. Right now is a fast and simple way to create apps in a modular fashion, it's less complex than Angular (the most popular choice now a days) but this improvement comes with a price, as this and other React related topics in this forum can prove.

 

Also is worth noticing that, as BowserKingKoopa and other users have mention, nothing has been broken and/or working in a strange fashion mixing GSAP and React. I've played with some simple examples of React and GSAP using GSAP to work with the DOM nodes as refs and not piping anything GSAP related through the state to avoid rendering the React component on every GSAP tick (every 16ms approximately) because I don't see how that's necessary. And also while animating a DOM element I've changed the value of a state property (which triggers a re-render of the component) and the GSAP instance animating the DOM element also resides in the component's state.

 

My idea is to complete that sample with some nested components and more animations in order to publish it on GitHub and continue the discussion in these topics that have been created. Also I'd like to get some contributions from other users with some live samples of GSAP and React in order to create a collection.

 

Finally BowserKingKoopa I have one question regarding the plugin you linked. It hasn't been updated in two years and originally it's using a very old version of GSAP (1.12.1). Have you tried with a newest version of GSAP?, is there any interest by the creator or other user to update this to a newer version of GSAP?

 

Happy Tweening!!

  • Like 1
Link to comment
Share on other sites

Hi Rodrigo,

 

I'm currently using the plugin I linked (https://github.com/hzdg/gsap-react-plugin) with the newest version of React without any problem. It's a really simple plugin, maybe 50 lines of code. All it does it redirect all GSAP animations that target a React component through the React setState mechanism. So while I'm not the author of it, I think there hasn't been any updates because it's done.

 

It's the opposite of the approach you mentioned: "not piping anything GSAP related through the state to avoid rendering the React component on every GSAP tick". I tried that at first and quickly got tangled up. It was hard. I found that in my game I often needed React and GSAP to manipulate the same properties and trying to sort it all out became a source of many weird bugs. So now I'm piping EVERYTHING through React (using that plugin). So far so good. And it lets me keep my mind in "React mode". 

  • Like 2
Link to comment
Share on other sites

Yep, as you mention, in that case is better to do that. Normally I don't mix GSAP with state properties, but if there's no other option, as it is your case, that's the better option.

 

You're right the file is quite small actually:

 

https://github.com/hzdg/gsap-react-plugin/blob/master/gsap-react-plugin.js

 

I'll play with it and see what happens behind the scenes, mostly I'm interested in how React is working and if a new GSAP instance is being created on every render or not. But since you mention that there are no performance issues it doesn't seem to be a problem.

  • Like 1
Link to comment
Share on other sites

I'm glad there are ways to make it work with gsap, but I don't see the points Jack made being questioned.

 

I agree about the react "way of thinking" being more pleasant to the developer tho: inmediate mode, you don't have to think too much about edge cases, etc. But it comes at a price and with its own set of drawbacks.

 

Anyway I hope someone can post some examples, performance comparisons, etc, so we all can get a better understanding of all the particularities.

  • Like 1
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...