Jump to content
Search Community

React and GSAP

martis 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 not very familiar with React, but couldn't you just use a closure & variable like:

var _reactObj = this; //this variable is the key
Draggable.create(ReactDOM.findDOMNode(this), {
       type:"rotation", 
       throwProps:true,
       onRelease: function() {
            //reference the variable here.
            console.log(_reactObj.props);
       }
});

?

  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...

Thanks so much for this, I too am getting into react and tying it in to greensock.

 

I will look at the key lifecycle and virtual dom concept since you mentioned it..

 

I've been using greensock since the as3 days (and love it). Over the past year I've been using React full time. 

 

I want to echo what Steven has said. The react questions that seem to be popping up when linked to animation and/or gsap often appear to stem from a lack of understanding about how React works - especially regarding the virtual dom and the importance of the key attribute and lifecycle methods. 

 

Jack has asked for examples of gsap breaking react (in a few threads I believe) but no examples have really popped up. There is no doubt that the linked enhancer above can help smooth out things - but you definitely can work with gsap+react without it.

 

 

Simple things to remember:

 

Use ref instead of findDOMNode

 | In most cases, you can attach a ref to the DOM node and avoid using findDOMNode at all.

source: https://facebook.github.io/react/docs/react-dom.html#finddomnode

 

When using ref, prefer ref callback over the older (yet supported) string variation:

| If you are currently using this.refs.myRefName to access refs, we recommend using this pattern instead.

source: https://facebook.github.io/react/docs/refs-and-the-dom.html

 

Key is key

Key is super important with repeated elements because it's Reacts way of telling if its the same element or not. If an item in a loop has the same key on the next cycle, react won't attempt to unmount the old and mount a new, instead it will just update its props. This is really important for animations because you don't want the next cycle to remove an element that is currently animating. 

 

ReactTransitionGroup

Also very important when items are being added or removed to the DOM. By wrapping your element in ReactTransitionGroup, you can delay when an element is actually unmounted - meaning you can hold off until an animation is finished before an element is removed from the vdom. 

 

 

gsap is no different from all the other non-React-aware libraries out there. TinyMCE, Google Maps, etc can all work with React despite having very complex architecture. Before you scream - "but there is 'react-google-maps' and 'react-tinymce' on npm!" They are quite simple wrappers that, like above, utitilise the lifecycle methods and refs to tap into the dom while staying react.

 

 

Happy to throw some codepens together if needed. 

 

*Edit*

 

Super simple example, can provide more:

 

See the Pen qqWJzv?editors=0010 by cjke (@cjke) on CodePen

 

Things to note is that the overall state is kept declarative (as per Reacts liking). The component is given props about its current state (is it animating, etc) and a child component communicates its internal state outwards via callbacks (again this is standard React  - think like a normal input component, pass value={value} in and onChange callback). 

 

During the timeline animation, the state is maintained (the counter - ironically this is set is via gsap, but the counter state count could be from clicks or anything). 

Link to comment
Share on other sites

cjke would u say the docs are the best place to understand these "especially regarding the virtual dom and the importance of the key attribute and lifecycle methods. " or another resource, i found the docs explanation rather technical not that helpful

 

edit

 

i found this desc very helpful from a random site

 

componentDidMount is executed after first render only on the client side. This is where AJAX requests and DOM or state updates should occur. This method is also used for integration with other JavaScript frameworks and any functions with delayed execution like setTimeout or setInterval. We are using it to update the state so we can trigger the other lifecycle methods.

 

https://www.tutorialspoint.com/reactjs/reactjs_component_life_cycle.htm

 

 

I've been using greensock since the as3 days (and love it). Over the past year I've been using React full time. 

 

I want to echo what Steven has said. The react questions that seem to be popping up when linked to animation and/or gsap often appear to stem from a lack of understanding about how React works - especially regarding the virtual dom and the importance of the key attribute and lifecycle methods. 

 

Jack has asked for examples of gsap breaking react (in a few threads I believe) but no examples have really popped up. There is no doubt that the linked enhancer above can help smooth out things - but you definitely can work with gsap+react without it.

 

 

Simple things to remember:

 

Use ref instead of findDOMNode

 | In most cases, you can attach a ref to the DOM node and avoid using findDOMNode at all.

source: https://facebook.github.io/react/docs/react-dom.html#finddomnode

 

When using ref, prefer ref callback over the older (yet supported) string variation:

| If you are currently using this.refs.myRefName to access refs, we recommend using this pattern instead.

source: https://facebook.github.io/react/docs/refs-and-the-dom.html

 

Key is key

Key is super important with repeated elements because it's Reacts way of telling if its the same element or not. If an item in a loop has the same key on the next cycle, react won't attempt to unmount the old and mount a new, instead it will just update its props. This is really important for animations because you don't want the next cycle to remove an element that is currently animating. 

 

ReactTransitionGroup

Also very important when items are being added or removed to the DOM. By wrapping your element in ReactTransitionGroup, you can delay when an element is actually unmounted - meaning you can hold off until an animation is finished before an element is removed from the vdom. 

 

 

gsap is no different from all the other non-React-aware libraries out there. TinyMCE, Google Maps, etc can all work with React despite having very complex architecture. Before you scream - "but there is 'react-google-maps' and 'react-tinymce' on npm!" They are quite simple wrappers that, like above, utitilise the lifecycle methods and refs to tap into the dom while staying react.

 

 

Happy to throw some codepens together if needed. 

 

*Edit*

 

Super simple example, can provide more:

 

See the Pen qqWJzv?editors=0010 by cjke (@cjke) on CodePen

 

Things to note is that the overall state is kept declarative (as per Reacts liking). The component is given props about its current state (is it animating, etc) and a child component communicates its internal state outwards via callbacks (again this is standard React  - think like a normal input component, pass value={value} in and onChange callback). 

 

During the timeline animation, the state is maintained (the counter - ironically this is set is via gsap, but the counter state count could be from clicks or anything). 

Link to comment
Share on other sites

cjke would u say the docs are the best place to understand these "especially regarding the virtual dom and the importance of the key attribute and lifecycle methods. " or another resource, i found the docs explanation rather technical not that helpful

 

Yeah fair question, for lifecycle, I would say the official docs are really good: https://facebook.github.io/react/docs/react-component.html

 

For "key", the docs are less obvious, especially the deep down importance - I feel they explain that you must include it, but not really "why".

This part of the docs is also good: https://facebook.github.io/react/docs/reconciliation.html#keys (the whole page is interesting, but keys in particular). 

 

Mark Erikson keeps an updated list of all the best tutorials related to React, there are a lot, but worth checking out some of the non-redux ones: https://github.com/markerikson/react-redux-links

 

Alternatively, feel free to ask here and I will do my best to answer (if I can!)

  • Like 2
Link to comment
Share on other sites

  • 2 months later...

What are the thoughts on using Greensock libraries with React Native? This is a very different animal than traditional react.js since there is no DOM. The current animation libraries available for React Native to put it bluntly, suck. I have often dreamed of being able to use the phenomenal Greensock libraries for native app development.

 

Are there any approaches to using Greensock with React Native that would work? 

Link to comment
Share on other sites

I've yet to actually play with React Native, always leaning towards responsive sites instead. 

 

Was there a particular problem you were hitting? 

 

Btw - agree on the default transition / animation solutions for React. That's why I was so happy when I found it so simply to use React with Greensock - best of both worlds. 

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

I have been using React and GSAP together since react was first created.

 

I have tried using it in a number of ways, but have found that tweening values in vanilla javascript objects combined with the use of the greensock onUpdate function (combined with onUpdateParams) and then pushing the values into a react component has been the cleanest.

 

This completely avoids the need for using findDOMNode (or getDOMNode if you have an older version of React).

  • Like 1
Link to comment
Share on other sites

  • 2 months later...
On 3/26/2017 at 2:04 AM, t.coenradi said:

I have been using React and GSAP together since react was first created.

 

I have tried using it in a number of ways, but have found that tweening values in vanilla javascript objects combined with the use of the greensock onUpdate function (combined with onUpdateParams) and then pushing the values into a react component has been the cleanest.

 

This completely avoids the need for using findDOMNode (or getDOMNode if you have an older version of React).

Hi @t.coenradi would you happen to have any kind of example of what you described?

Link to comment
Share on other sites

  • 1 month later...

In case anybody's still looking for a super simple example, here's a basic component with an animated gsap title:

 

import React, { Component } from 'react';
import { TweenMax } from 'gsap';

export default class AnimatedTitle extends Component {
  componentDidMount() {
    TweenMax.to(this.title, 3, { x: 300 });
  }

  render() {
    return (
      <h1 ref={h1 => { this.title = h1; }} >Animated Title</h1>
    );
  }
}

 

  • Like 2
Link to comment
Share on other sites

We're using GSAP quite extensively in http://rhinogram.github.io/rhinostyle/ without any 3rd party libs to control how we interact with it. You can also check out this branch https://github.com/rhinogram/rhinostyle/tree/zach/modal-append-example that is an update to how we deal with Covers and Modals (that need to append to the body) by using https://github.com/jpgorman/react-append-to-body

  • Like 1
Link to comment
Share on other sites

 
 
Here's the thing:
I think they are super simple examples floating around
but not much more harder than that.
I have been looking for how to do:
 

Shared Element Transitionsanimation pattern where you reparent an element w/ a translate and tween to new pos? See tweet for example

 
 
Staggered Tweening - Animating the elements within the component
<Header />
- ele1
- ele2
 
<Main />
- ele1
- ele2
 
<Footer />
- ele1
- ele2
I dont want to only animate the header Main and footer but the elements within them. So the ele1 in <Main/> fades in right after the ele2 in <Header/>
 
---
Ive considered AnimatedJS but despite its power, its a completely different paradigm  and more verbose code.
If anyone has suggestions on achieving the above let me know. When I figure it out I will definitely share and open source it.
With that said thanks for sharing your code zachschnackel. .
  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

Adding to Steven's example as I believe it works really well. This is how I did it, please let me know of any caveats you find if you try this approach as I'm still experimenting with it.

1. Install gsap using npm or yarn.

npm install gsap

yarn add gsap


2. Next import TweenMax (or anything else you need) into your component. Create an animation and pass it as a ref to the element you want to animate.

import React, { Component } from 'react'
import { StyleSheet, css } from 'aphrodite'
// Importing TweenMax and the Bounce ease. You need to import other things from it as needed.
import { TweenMax, Bounce } from 'gsap'

// Create a component as usual.
export default class UserCard extends Component {
  render() {
    return(
     // Pass your animation as ref. (see react docs).
     <div 
      	ref={(card) => { TweenMax.to(card,2,{rotation:360, ease:Bounce.easeOut}); }}
  	className={css(styles.userContainer)}>
        <p>User info here.</p>                                                                                     
     </div>
    )
  }
}

// Style your components or add other stuff as usual.
// .css stylesheets work as well.
const styles = StyleSheet.create({
  userContainer: {
    display: 'flex',
    flexDirection: 'column',
    width: '250px',
    borderRadius: 7,
    border: '1px solid rgba(0, 0, 0, 0.2)',
    margin: '0px',
    boxShadow: '2px 2px 2px 1px rgba(0, 0, 0, 0.2)',
    marginBottom: '20px',
    background: "#fff",
  }
})

// This approach let's you export default Redux's connect()


Known issues:

  1. If a style is applied using styled components, GSAP won't be able to change it. A solution could be using .css stylesheets.
  • Like 1
Link to comment
Share on other sites

@Cristiano very nice example. 

 

Just be mindful of doing anything in render. You are better off leveraging the lifecycle methods for components. 

 

If you get a tic, check out my previous posts, and in particular this codepen 

See the Pen qqWJzv?editors=0010 by cjke (@cjke) on CodePen

If you have a specific question, please ask, and I can do my best to answer. 

 

 

  • Like 2
Link to comment
Share on other sites

  • 3 months later...

All the exemples are driving me nuts, been reading for 12 hours, and i'm still nowhere to getting this to work, the previous exemple does not work with react V16 , and IT needs react-transition-group but it has changed too, anyone with a solution ?? React is not a small player , this should be somewhere here in the docs. 

Link to comment
Share on other sites

@axe-z - not sure if you mean my example when you say "the previous example". It's a shame they are you driving you nuts, I simply put them up to try to help other people correctly set up React with Greensock. 

 

Regardless - I updated my codepen with a R16 version:

See the Pen MOrrEL?editors=0010 by cjke (@cjke) on CodePen

 

It should be noted I did nothing but update the cdn links - no code changed for it to work with R16. You might be talking about different examples, in which case, it might help to outline what isn't working? 

 

Its worth noting you don't need react-transition-group to use greensock - in fact, I would say you should probably pick one library or another. 

 

 

  • Like 2
Link to comment
Share on other sites

@axe-z I  haven't played too much with React 16 and GSAP yet but it seems that it hasn't change that much. With that in mind this samples use React 15, Transition group 2.2.0 (latest is 2.2.1) and React Router 4.1.2 (latest 4.2.0) so they should come in handy in order to get you started.

 

Simple component transition using GSAP
https://codesandbox.io/s/yvYE9NNW

 

Using React Router to animate the mounting and unmounting of the components:
https://codesandbox.io/s/mQy3mMznn

 

Happy Tweening!!

  • Like 5
Link to comment
Share on other sites

Does not work anymore... Issues when using routers, animation not waiting before the component is out, it looks cheap. Really bummed out about this. I ll have to go with lesser js animation apis. if only it could work with specific component lifecycles like : componentWillAppear / componentWillLeave 

Link to comment
Share on other sites

Hi,

 

Basically the React and React Router (RR) code came from the samples in this issue of the React Transition Group (RTG) repo, so not too much official documentation regarding this:

 

https://github.com/reactjs/react-transition-group/issues/136

 

RR basically relies on CSS Transitions :blink:mainly and that's kind of the official "way to go" in terms of animating route changes. Also you have to keep in mind that the code also has to accommodate for some problems regarding RR, mentioned in this issues:

https://github.com/ReactTraining/react-router/issues/5039

 

https://github.com/ReactTraining/history/issues/470#issuecomment-345422719

 

The rest comes from the API of RTG. It might seem a bit daunting at first, but the code is not that complicated actually.

 

What part is giving you trouble?

  • Like 1
Link to comment
Share on other sites

I think I have cracked it, I do not see any issues right now...  using both   <TransitionGroup> and
    <Transition>  with  GSAP , based on the code you gave me , made it simpler and faster. Without the FIXED position that was

problematic since you cannot scroll . if you ever need it, just give me a shout. My english is not good enough to publish. 

  • Like 1
Link to comment
Share on other sites

  • 2 months later...

Hi there,

 

I'm a newbie to both react and GSAP. I'm trying to get this working on react-native. I can get the block to display but nothing happens (no errors either) when I hit 'Animate'.  Here is my code

 

import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { TimelineLite } from 'gsap';

class TLine extends React.Component {
  animate = () => {
    var animation = new TimelineLite()
    animation
      .to(this.box, 1, { x: 200 })
      .to(this.box, 1, { y: 200 })
      .to(this.box, 1, { x: 0 })
      .to(this.box, 1, { y: 0 })
  }
  render() {
    return (
      <View style={textStyles.container}>
        <Button style={styles.button} onPress={this.animate} title = 'Animate' />
        <View style={styles.box} ref={box => this.box = box} className="box" />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  button: {
    width: 200,
    height: 45
    // border: 'none',
    // outline: 'none',
  },
  container: {
    padding: 100,
  },
  box: {
    marginTop: 10,
    width: 100,
    height: 100,
    backgroundColor: '#ffc107',
    borderRadius: 4
    // boxShadow: '1px 1px 27px rgba(0, 0, 0, .3)'
  }
})

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>This is a test for GSAP </Text>
        <TLine />
      </View>
    );
  }
}

 

Can anyone point to why it doesn't seem to work? Or, how to debug it since I don't see any errors?

 

Thanks.

Link to comment
Share on other sites

  • 3 weeks later...

GSAP'ers, I'm trying to understand what I'm missing with a simple use case. I managed getting an example I found to work but when trying out something different out, I see no animations. Here is my simple ReactJS and GSAP test.

 

Package versions: gsap": "1.20.4", "react": "16.2.0"

 

 Viewing the console, there are no errors. I do see "onStart" and "onComplete" printed. But no animation. 


 

import React, { Component } from 'react';
import {TweenLite, Linear} from 'gsap';

export default class TextExample extends Component {
  animate = () => {
    TweenLite.to(this.titleElement, 2, {text:this.props.endTitle, ease:Linear.easeNone})
             .eventCallback("onStart", () => {console.log("onStart");})
             .eventCallback("onComplete", () => {console.log("onComplete");});
  }

  render() {
    return (
      <div id="myId"
          ref={elm => this.titleElement = elm}
          onClick={this.animate}>
            {this.props.startTitle}
      </div>
    )
  }
}

 

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