Keep Moving Forward | X-Team Magazine

Animating React Applications

Written by Joseph Rex | Aug 8, 2017 4:00:00 AM

Animation is king in the 21st century. When you look around, you could almost see real world objects interpreting as digital animations. Ever noticed how futuristic movies have moving images in newspapers? Or the animated hologram commercials on streets? This is because businesses cannot and will not resist leveraging on the attention and attraction of humans to moving objects. Marketing has been the biggest income generator for businesses... The world bleeds marketing, and animation has played a significant role in that.

Just like billboards and posters that have moved from being static to being animated, websites and applications are jumping on this animation ride as well. Here at X-team, since the homepage changed from a static image to a background video, I bet the bounce rate has reduced because I can personally say that the moving background has increased my attention span. Just an extra minute to see how an animation or video ends, an extra opportunity to read everything in the header section. Moreover, for a product page, that would also equal higher conversion rates.

You may already see some of the importance of animation in applications now, but why React? Many applications are being built in React today because of its clever algorithm and programming approach. React applications encourage separation of concerns and less shabby code with its declarative style. When used properly, you could see that the architecture of React makes codebases maintainable.

The first closest thing to animation is state transitions and you can do this with just CSS. Transitioning from one state to another could ease longer processes by making them look shorter with the perception of continuity when there are no visual breaks. CSS could be sufficient for tweening states of an object already visual in the DOM or for looping animations like this:

or other time-based animation with a finite end.

Hover the demo and click rerun if you missed the animation on the phone.

However, when adding items to the DOM, we cannot easily create a smooth transition. The display property is not animatable hence we cannot animate elements that did not exist in the DOM before or were hidden with a display: none. This is where React animations come in.

Consider the following example

Using ReactCSSTransitionGroup

If we need to fade the new list entries in, here is how we could go about it with ReactCSSTransitionGroup

To animate the insertion of an element into the DOM, we have to hide it right before it gets mounted on the DOM, then animate as it reveals when it is already inserted in the DOM. This jQuery example might help you understand the process:

To do this in React, we need to be able to set animation on ComponentDidMount . If animating a fade out, then also ComponentWillUnmount.

There are no easier ways to control animations declaratively at this stages of the lifecycle, so ReactCSSTransitionGroup helps to address that with its syntax

<CSSTransitionGroup
  transitionName="x-demo"
  transitionEnterTimeOut={500}
  transitionLeaveTimeOut={300}
 />

When a transition name is set, it uses that as a namespace for CSS classes that will create the mount and unmount tweens. For the name x-demo in the example above, we have to create the following CSS classes:

.x-demo-enter {
  opacity: 0.01;
}

.x-demo-enter.x-demo-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.x-demo-leave {
  opacity: 1;
}

.x-demo-leave.x-demo-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}

and style it however we want for the transition effect needed.

Using ReactMotion

In his talk The state of animation in React, Cheng Lou talked about the limitations of CSS animations being time-based. CSS animations could be really performant and sleek when used right, but they only react to time. To create more reactive animations (user-action based), more dynamism is needed, and JavaScript is usually the tool for the job.

Here is a clear picture, how would you animate the motion from a drag?

or a physics/spring based animation.

There is also a stagger effect in the last example. It can be somewhat achieved in CSS, but it would feel unreal as each of the objects in the stagger cannot dynamically be based on other. You would have to set some predefined time for each object that may end up not being accurate. Here is an example of a CSS animation that tries to achieve a bounce against a surface (physics).

As beautiful as that is, you could notice that the ball compresses right before it hits the ground hence the pressure is not caused by the collision.

Here is another example with just CSS that looks a little more precise in its timing:

The problem, however, is this would be a lot of calculation if it were to be more accurate and done with just CSS. Acceleration increases due to the resulting velocity from collision against the ground, and the distance will reduce on each bounce as the velocity reduces.

The equation above shows that the acceleration of particles is the second derivative of its position x with respect to time t.

In the last example, the camera positioning in the scene also helps create an illusion of accuracy.

React-motion, as shown in previous demos, has a more robust API compared to ReactCSSTransitionGroup. Its spring could be used on any property at all to animate from one state to another. My examples used the <Motion> and <StaggeredMotion> but you could also use <TransitionMotion> for mounting and unmounting animations. With ReactMotion, there is absolutely no need for ReactCSSTransitionGroup.

Using ReactMove

ReactMove is similar to ReactMotion but with a slightly different API. The spring is separated as a different library, so you do not have to load it when you are not making physics-based animations. It also has some built-in easings and lets you create custom easing. It is difficult to decide between ReactMove and ReactMotion. You just have to go with what works for you, but I urge you to give ReactMove a try.

Using GSAP

The biggest limitation with every step mentioned above is they are only good at animating from one state to another. What if you need 3 or more sequences for your animations — a timeline if I may? GSAP does one thing, and it does it well. It makes great animations! And its TimelineMax is well-packed for your timeline needs.

The biggest benefit of using GSAP is you do not have to worry about cross-browser inconsistencies as it handles that. GreenSock also has a great community to get feedback and support.

Here is an example of GSAP timeline in use:

This combines an element fadeOut, a repositioning with a bounce ease, and staggers. GSAP also has nifty plugins for physics, SVG morphing, and more.

Final Thoughts

There is nothing as important as using the right tool for the job. If you have ever had to ask yourself, "When do I need an animation library in React?" I would like to believe this article has helped answer that. Just like GSAP was used here, you could also use animation libraries like mo.js, threejs, pixi, or any other good ones you may find.