Peter Ekene Eze Learn, Apply, Share

React Spring vs Animated

4 min read 1386

The Animated library is designed to make animations fluid, powerful, and easy to build and maintain. It focuses on declarative relationships between inputs and outputs, with configurable transforms in between, and simple start/stop methods to control time-based animation execution.

React Spring can be seen as an extended version of the Animated library. It builds upon Animated’s foundation, making it leaner and more flexible. It inherits React Motion Declarative API and goes to great lengths to simplify it. It has lots of useful primitives, can interpolate mostly everything and, last but not least, can animate by committing directly to the DOM instead of re-rendering a component frame-by-frame.

Prerequisites

In order to properly follow along in this post, it is required to have a basic understanding of the following technologies:

Setting up Animated

You can use npm to add the Animated library to your project:

npm install animated

Then import it into your project like this:

import Animated from 'animated/lib/targets/react-dom';

Setting up React Spring

Just like Animated, you can install the React Spring library via npm like this:

npm install react-spring

And import it into the project for use like this:

import { Spring } from 'react-spring'

Platform targets

The Animated library specifically targets the DOM as can be seen from the import statement:

import Animated from 'animated/lib/targets/react-dom';

Unlike the Animated library, React Spring allows you to build for targets other than the DOM:

// The default export is valid for react-native as well
import { Spring } from 'react-spring'

// react-konva
import { Spring } from 'react-spring/dist/konva'

// Any other target or platform
import { Spring } from 'react-spring/dist/universal'

Interpolation

Consider an animated box that rotates for a certain period of time and dissociates in parts via Interpolation, the Animated library will interpolate it between an input range of numbers between (0,4) and then a specified set of output range values in degrees which falls between (0 and 360 degrees):

// ... Animated
render() {
  return (
    <div className="App">
<Animated.div
  className="box"
  onClick={this.toggle}
  style={{
    transform: [{
    rotate: this.state.anim.interpolate({
    inputRange: [0, 4],
    outputRange: ["0deg", "360deg"]
  })
  }
],
position: "relative"
}}/>
  </div>
  );
}

With React Spring, the from attribute sets the rotation to a steady “0deg” and rotates it to a 90% turn which makes for a more liquid and declarative rotation:

// ... React Spring
render() {
  return (
    <div className="App">
<Spring
  from={{ rotation: "0deg" }}
  to={{ rotation: this.state.turn ? "0" : "90%" }}>
  
    {({ rotation }) => (
  <div
  className="box"
  style={{ transform: `rotate(${rotation})` }}
  onClick={this.toggle}>
    {this.state.deg}
  </div>
 )}
</Spring>
    </div>
  );
}

In this aspect, if you prefer to type less code and maintain a clear level of understanding, React Springs takes the cake because it doesn’t handle just numbers. With React Spring you can interpolate almost everything ranging from colors to angles, relative lengths, SVG paths etc.

However, if you don’t have any problems with the conventional alternative procedures that involves typing as much code as is necessary, interpolating only the relevant elements and generally sticking to familiar routes, then the Animated library provides that consistency here.

Declarative

React Spring embraces the declarative nature of React. It has a simplified and declarative API that allows the creation of complex animations with a few lines of code. It also exposes an imperative API, in case you want to manually specify unique controls for your animation processes.

Declaratives in React Spring:

// ... React Spring
class App extends React.Component {
state = { toggle: false };
handleToggle = () => this.setState(state => ({ toggle: !state.toggle }));
render() {
  return (
    <div className="App">
<Spring
  from={{ scale: 0.5 }}
  to={{ scale: this.state.toggle ? 0.5 : 1 }}>
    {({ scale }) => (
<div
style={{ transform: `scale(${scale})` }}
className="box"
onClick={this.handleToggle}/>
)}
</Spring>
  </div>
  );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Animated on the other hand has an imperative API which means that creating animations will involve a rather manual process and more verbose code.

Declaratives in Animated:

// ... Animated
class App extends React.Component {
  state = { toggle: false, anim: new Animated.Value(1) };
  handleClick = () => {
    this.setState(
      state => ({ toggle: !state.toggle }),
      () => {
        this.state.toggle
          ? Animated.timing(this.state.anim, { toValue: 0.5 }).start()
          : Animated.timing(this.state.anim, { toValue: 1 }).start();
   }
  );
};
render() {
  return (
  <div className="App">
    <Animated.div
      className="box"
      style={{ transform: [{ scale: this.state.anim }] }}
      onClick={this.handleClick}/>
  </div>
  );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

From the examples above, React Spring’s to and from attributes make it easy to change the scale property of an element from one state to another and with it, the library animates the element accordingly.

For Animated, we have to set an initial anim value in the component’s state and update it with a toValue in the Animated.timing method and then call a start method on it before the library can carry out the animation.

Primitives

React Spring contain primitives like <Spring>, <Trail>, <Transition>, <Parallax> for animations like trails, transitions, parallax and so on. These primitives help you achieve primitive animations without the inconveniences of manually writing all the required logic.

Just like declaratives, Animated does not contain primitives. In order to achieve Primitive animations, you’ll have to manually create the required animation, and this involves writing more lines of code.

Performance

Since React Spring is an enhanced form of the Animated library, it leverages its ability to apply animations without relying on React to render updates frame by frame, making it very performant. The Animated library makes up in performance as it also applies updates to animations directly to the DOM in a requestAnimationFrame which ensures the animations render within the required frame and doesn’t cause “jank”.

Compared to the Animated library, React Spring covers more grounds as it combines the existing efforts of both the Animated library and React Motion to offer a more powerful animation system.

Declarative Primitives Interpolations Performance
Animated
React-spring

If by design, you have no explicit need for declaratives and primitives in your animations, Animated is performant enough to build out your ideal animations with the rich interpolation features it offers. If however, you want it all together, React Spring has more to offer with the inclusion of declaratives and primitives.

Ease of use

Getting started on both libraries is quite simple as we demonstrated at the beginning of this post, however, a majority of the very useful information about Animated and the features it offers is found within the React Native documentation which makes it a bit tricky when searching for learning resources on other information about Animated. The documentation doesn’t provide very simple steps on how to easily get started for people with no existing knowledge of animations.

React Spring, however, has rich documentation with several examples that provide an easier guide to learning how to use the library in making animations in React. There are also a few React Spring tutorials and articles online.

Community support

With about 94 contributors and 13.9k stars on GitHub for React Spring compared to about 10 contributors and 9k stars for Animated, React Spring has stronger community support regardless of being very new compared to Animated. React Spring has seen much more contribution from the React developer ecosystem since inception than Animated has.

React Spring also has backers and sponsors who donate funds to support and ensure its development is continuous. Here are the code frequency graphs of both technologies according to their Github repositories.

React Spring code frequency
React Spring code frequency
Animated code frequency
Animated code frequency

React Spring also has more active code contribution, as seen in the images above, which shows that it has most likely seen more improvements to catch up with JavaScript’s fast-paced growth.

Final thoughts

React Spring and Animated are both great animation tools that help us create nice user experiences. Choosing between them depends entirely on your project needs and architecture. It is worthy to note that this post isn’t meant to create hype or throw shade at any of these tools, but rather offer a better understanding of their strengths and weaknesses so you can make an informed decision. Cheers!

 

Plug: , a DVR for web apps

LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Peter Ekene Eze Learn, Apply, Share

Leave a Reply