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.
In order to properly follow along in this post, it is required to have a basic understanding of the following technologies:
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';
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'
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'
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.
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.
// ... 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.
// ... 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.
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.
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.
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.
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 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.
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!
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]