Introduction to react-spring for data visualization
Web animations fall into two main categories: CSS and spring-based animations.
In this lesson, we’ll explore react-spring, a popular library for creating spring-based animations in React. Let’s see how to use it to bring our graph elements to life.
Animating a Circle
Let’s start with something simple for this first lesson.
Our goal is to animate a circle moving smoothly from one position to another. Here’s what the final effect will look like:
Pretty cool, right? 🙃
To achieve this, we’ll use react-spring, the most popular JavaScript library for spring-based animations.
react-spring
homepage. The most famous lib for javascript animation (28k stars on github)
Full code
react-spring
is incredibly powerful, but it can be a bit tricky to grasp, and I personally find its documentation a little unclear. 😞
For now, the two key features we need are the useSpring
hook and the animated
component.
With these two tools, we can create a Circle
component that accepts a position
prop. Whenever a new position
value is passed, the circle smoothly transitions to its new location.
Here’s how the Circle
component looks:
import { animated, useSpring } from 'react-spring';
export const Circle = ({ position }) => {
const springProps = useSpring({
to: {
position: position
},
});
return (
<animated.circle
r={38}
cy={50}
cx={springProps.position}
/>
);
};
Explanation
In this code, we’re creating a simple Circle
component that renders one circle. The component takes a position
property, which controls the circle’s X position.
Whenever this prop updates, the circle’s position will change, but it will happen smoothly!
Here’s a breakdown of what’s happening:
🚚 Import
Once installed with a classic npm install react-spring
, we need to import:
useSpring
: a hook that helps us create animated values.animated
:a special version of elements (like<circle>
) that can be animated.
🌸 Using useSpring
- The
useSpring
hook is used to define an animation. It accepts an object where we specify the properties to animate and how to animate them. In this case, we're animating theposition
. - We now have access to
springProps.position
. If the position changes from0
to100
,springProps.position
will smoothly transition through values like 1, 3, 10, 15, and so on, until it reaches 100.react-spring
handles the calculation of these intermediate values for us!
🔗 Binding the Animation to the Circle
- Instead of using a regular
circle
SVG element, we useanimated.circle
. React-spring provides its own animated version of all HTML and SVG elements! - Instead of passing
position
directly to thecx
property, we passspringProps.position
, which contains all the intermediate values, ensuring the circle moves smoothly.
A very basic animation using react and react-spring.
🔥 Spring Config
Spring animations follow physics laws to make the animation feel natural. There are three key properties you can control to adjust the feel of the animation: mass
, friction
, and tension
.
You can customize these properties in the useSpring
hook like this:
const springProps = useSpring({
to: { position, color },
config: {
mass: 5,
friction: 120,
tension: 120,
}
});
But honestly, I strongly advise using one of the presets provided by the library, as they offer great results right out of the box.
Check out the preset effects in the example below:
react-spring
offers a few presets for the animation feel. Try them in this sandbox!
To use one of the presets, you can do something like this:
const springProps = useSpring({
position: 100,
config: config.default
});
Deriving Values
Animating a value directly using react-spring, like we did for the position property, is straightforward.
However, in data visualization, we often need to derive one value from another.
For example, suppose we want the size of the circle to be proportional to the X position. You might think that we could simply use the springProps.position
value as a regular number, like this:
return (
<animated.circle
cx={springProps.position}
cy={50}
r={springProps.position / 10} // This will not work! 😱
/>
);
Instead, to achieve this, we need to use the to()
method of the springProps.position
property, like so:
return (
<animated.circle
cx={springProps.position}
cy={50}
r={springProps.position.to((pos) => pos / 10)}
/>
);
This is called interpolation in react-spring
terminology. You can learn more about it in the full documentation here.
Let’s take a look at the result!
Smooth animation where circle size is derived from X position.
Animating Text
So far, we’ve only animated numerical values—like smoothly transitioning the position from 1
to 100
.
But react-spring
is much more powerful than that! It can animate almost anything, including text and colors!
In the example below, watch how the number evolves progressively:
Demo: react-spring can also animate text, colors and so much more!