Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Dipscom

GSAP with Create React App

Recommended Posts

If you are someone like me and has ZERO experience with React, Facebook's Create React App, webpack and the sort, you might want to have a read about my adventures working in a live project here.

 

As stated I'm working in a project that uses the Create React App - The idea is quite cool. They hide away the vast majority of the config and common files that end up being clutter when working on a simple project. The upside is that things are super simple and look really neat. The downside is that for someone who has no idea what one's doing, it's very confusing.

 

I will try and put a little summary of what's happening so that my pain can be shared.

 

Day 1:

 

Read this post from cjke.7777 and digest it completely, it's full of very important and useful information.

 

Don't include GSAP in your bundled files, there's really no reason for that. GSAP is hosted in a CDN, make use of it and all of its benefits. 

 

Pro Tip from OSUblake, you don't need to do anything else after including the CDN. No 'require', no 'include', nada.

 

Gotcha 1 - The linter included in the Create React App will throw a hissy fit and fail to compile because TweenMax is a global variable. In their docs they suggest two options: 1) Creating a new variable directly from the window Object (please don't). 2) Adding a comment line for the linter to ignore (the lesser of the two evils, in my view).

 

Your tween will end up something like:

TweenMax.from(this.el, 1, { // eslint-disable-line
 autoAlpha:0,
});

Don't worry about the 'this.el' bit, I'll explain it later. After all, I still need to finish this project in time. 

 

Bonus reading (Also from OSUblake):

https://medium.com/@cheapsteak/hi-tadeouy-thank-you-for-the-kind-words-44dfc75190b8

https://medium.com/@cheapsteak/reusing-reacttransitiongroup-animations-with-higher-order-components-1e7043451f91

 

Just don't worry about using findDOMNode as cjke.7777 points out in his post.

 

  • Like 1
Link to comment
Share on other sites

Gotcha 2 (Read Gotcha 1 for context):

 

May the gods be mercy upon you if you decide to use ease...

animateOut(callback) {
 TweenMax.to(this.el, 1, { // eslint-disable-line
   autoAlpha:0,
   x:"+=100",
   ease: Power2.easeIn, // eslint-disable-line
   onComplete:callback
 });
}

If anyone knows a better way of getting around this without creating a million references to the window Object and/or disabling/editing the linter, let me know. 

 

Otherwise, this will be painful.

Edited by Dipscom
See post bellow by mighty GreenSock
Link to comment
Share on other sites

You should be able to just put the ease in quotes:

ease:"Power2.easeIn"

We added that a while back as a convenience, but it's not commonly seen/used. :)

 

Does that help?

  • Like 4
Link to comment
Share on other sites

Indeed it does. 

 

One less thorn in the path to completion.

 

For reference, this works:

animateOut(callback) {
 TweenMax.to(this.el, 1, { // eslint-disable-line
  autoAlpha:0,
  x:"+=100",
  ease: "Power2.easeIn",
  onComplete:callback
 });
}
Link to comment
Share on other sites

Day 3:

 

React's TransitionGroup is your friend

 

Docs - https://facebook.github.io/react/docs/animation.html#low-level-api-reacttransitiongroup

 

Things to be aware of:

 

Inside the TransitionGroup, the children must have a key. From React's docs:

 

You must provide the key attribute for all children of ReactCSSTransitionGroup, even when only rendering a single item. This is how React will determine which children have entered, left, or stayed.

 

 

And the Objects inside the TransitionGroup must be React Objects, not DOM objects. DOM objects don't trigger the necessary animation lifecycle callbacks. That sounds quite obvious but it took me half a day to click into that...

 

This, bad:

import React from 'react';
import TransitionGroup from 'react-addons-transition-group';

...

render() {
 return (
  <TransitionGroup >
   <div>Stuff to be animated</div>
  </TransitionGroup> )
}

This, good:

import React from 'react';
import TransitionGroup from 'react-addons-transition-group';

...

render() {
 return (
  <TransitionGroup >
   <AReactComponent />
  </TransitionGroup> )
}
  • Like 2
Link to comment
Share on other sites

Please keep sharing these tid-bits that you're learning along the way, Dipscom. This may become a useful bookmark for folks learning React + GSAP. 

  • Like 1
Link to comment
Share on other sites

Just a quick heads up, I am glad to see this thread.

 

I have a simple example using react and gsap. (thanks to OSU Blake and these forums btw)

Its really simple but ill share

 

"styled-components" 

Some may know I hate CSS, but I've found that using a library called "styled-components" has made using CSS a bit more of a joy to use with react. The css is separated by component, which fits my thinking better. I don't have go to a different file and scroll through what I don't need to find a particular style.

 

"not use greensock? I dont wanna"

To the point about ReactTransition Group on this thread, I have to say, this may sound arrogant,

but i never got the need for 

React's TransitionGroup or https://facebook.github.io/react/docs/animation.html

 

As long as I put the code in the right lifecycle methods, my instinctive response is

"why do that when I could just use Greensock to accomplish the same with less code?"

 

But I am still open to it. Thanks for this thread. If its okay with the original poster, I will share my learnings here.

  • Like 2
Link to comment
Share on other sites

So, the deadline looms... Hence the lack of more comments from me. I need to first get this baby out of the room before I am allowed to spend time loitering in online forums... ;)

 

But, there's some time for a quick comment.

 

As alwayzambitious has said, using React's TransitionGroup is not mandatory. It will depend on the setup. You do, as he correctly points out, need an understanding of the lifecycle methods.

 

As a super simple example. Say you have one tiny component that you know it will only be rendered once and will not be updated. There's no need for TransitionGroup, for key, for ref or anything complicated at all. All you need is componentDidMount.

class HelloMessage extends React.Component {
 componentDidMount() {
  TweenMax.to("#box", 1, {yPercent:100, ease:Power2.easeInOut, repeat:-1, yoyo:true})
 }
 render() {
  return <div id="box">Hello {this.props.name}</div>;
 }
}

 

Live in CodePen:

See the Pen MJbgBM by dipscom (@dipscom) on CodePen

  • Like 1
Link to comment
Share on other sites

Hey @alwayzambitious,

 

Did you see this demo I made the other day?

 

See the Pen f266abee469b9ebec5663cb7649f2874?editors=0010 by osublake (@osublake) on CodePen

 

Click the add box button really fast. I don't think you can do those animations using lifecycle hooks in React. It's not the animation to add a component that is the problem, but the animation to remove a component. You can't play a leave animation inside the componentWillUnmount method as it's going to be immediately removed from the DOM.

 

This is the problem ReactTransitionGroup tries to solve. I know you've messed with Angular, and ReactTransitionGroup is based on it's animation module, ngAnimate. Check out a version of that demo using Angular.

 

See the Pen 5d9d6fe688766b469f5d4db88ef069b2?editors=0010 by osublake (@osublake) on CodePen

 

So Angular's enter and leave animation methods are similar to componentWillEnter and componentWillLeave.

 

See the Pen vgyYqb?editors=0010 by osublake (@osublake) on CodePen

 

One problem though. The React version doesn't seem handle multiple clicks that well. That's because ReactTransitionGroup can't handle interruptible animations. The solution? Try ReactTransitionGroupPlus. It seems to work well. You can compare the different approaches with this demo. Notice how the animations don't build up when you rapidly click the animate button using ReactTransitionGroupPlus.

 

http://cheapsteak.github.io/react-transition-group-plus/

 

.

  • Like 4
Link to comment
Share on other sites

  • 2 weeks later...

One might have noticed the deadline got the best of me eventually. Now it seems to be live and I haven't received any late night calls/emails. Always a good sign.

 

Anyhow... Back to the matter at hand. Documenting my adventures with React and GSAP.

 

Here's a super simple use for the TransitionGroup I put together with some notes (for myself) and my reasoning behind it. Blake has given a more than thorough explanation of where to use it and its pitfalls. No reason to repeat.

 

See the Pen e4b13c1d2ddcec6eb3bb67068ca4e5e2 by dipscom (@dipscom) on CodePen

  • Like 2
Link to comment
Share on other sites

Do you have link to the site?

 

And I like your notes on what works and doesn't with the TransitionGroup.

 This would not work because of the ':' present inside the transition group 
 <TransitionGroup>
  {hours}:{mins}:{secs}
 </TransitionGroup>
 
 However, this would
 <TransitionGroup>
  {hours}{mins}{secs}
 </TransitionGroup>
  
 This would also work
 <TransitionGroup>
  {hours}<span>:</span>{mins}<span>:</span>{secs}
 </TransitionGroup>
  
 This would not work because the encompassing <div> is not a React component and therefore does not communicates with the <TransitionGroup>
 <TransitionGroup>
  <div>{hours}<span>:</span>{mins}<span>:</span>{secs}</div>
 </TransitionGroup>

 Here, we are only updating values, we are not adding or removing the components, which would trigger the lifecycle hooks
 <TransitionGroup>
  <Unit key="hours" number={this.state.hours} />
  <Unit key="minutes" number={this.state.minutes} />
  <Unit key="seconds" number={this.state.seconds} />
 </TransitionGroup>

.

 

  • Like 1
Link to comment
Share on other sites

For anybody who is having trouble wrapping your head around JSX and how the Virtual DOM works, you should check out this quick read.

https://jasonformat.com/wtf-is-jsx/

 

It will show you how to create your own JSX renderer and virtual DOM without any frameworks! It's not as hard or as magical as you may think. The virtual DOM is just a JSON object, and JSX is injected into a function by Babel. Pretty simple!

See the Pen c0d238276b4b1b9c4ab48e56100f75cf?editors=0010 by osublake (@osublake) on CodePen

 

And here's what that looks like without the JSX syntax.

See the Pen 44ff41ae5895ffe73c7b06deb3a46ff7?editors=0010 by osublake (@osublake) on CodePen

 

 

With JSX...

var foo = <div id="foo">Hello!</div>;  

Without...

var foo = h('div', {id:"foo"}, 'Hello!'); 

"h" is the name of a function that creates the DOM elements.

 

.

  • Like 2
Link to comment
Share on other sites

Do you have link to the site?

 

I do but if you think I will ever post it here, dream on... 

 

It's only live for two weeks, or so. Until Valentine's day. And, it needs to be rebuilt anyway, we were feeling our way in the dark in this project to the point that we decided we needed to scratch everything we had done three days before deadline and build it all again because we coded ourselves into a dead end. We ended up coding ourselves into another dead end again but this was close enough to the finish line that we got away with it. I want to spend some time and re-build it a third time with my newly found React knowledge to see what I can do now.

 

Besides, I spent so long bug hunting that I got no time to work on any of the animations so, it's pretty bare there.

 

I will, however, when life lets me, follow those links of yours, it will be super cool to know how it is done. Incidentally, how do you even get around all of this stuff, Blake?

Link to comment
Share on other sites

I made a fancier version of that first example. 

 

See the Pen YNEJZx by dipscom (@dipscom) on CodePen

 

This also makes use of the Web Visibility API, correctly, I think. In the first one, it's kind of botched but I will leave it like that so that I can remember from past mistakes.

Link to comment
Share on other sites

  • 11 months later...

This is kind of old but since I just started with a similar project, thought I'd chip in...

 

In React, just put this below your imports & above your react component declaration:

const T = TweenLite; // eslint-disable-line

 

, and then in your component use it as T.to() ... etc. = only 1 eslint-disable line.

 

 

  • Like 3
Link to comment
Share on other sites

  • 9 months later...

I have a fairly extensive and up to date knowledge of JS and jquery.  I read that react is a good match for GSAP.  I set out to learn react a few days ago and the deeper I get into it the more complex it gets.  I want to use GSAP to make simple banner ads.  Might being proficient in REACT be overkill?

Link to comment
Share on other sites

I am pretty sure you don't need React for banner ads ?

  • Like 2
  • Thanks 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.
×