Animations are the important parts of UX that give an additional feel to the users and add some awesomeness to the application. But implementing animations is not that easy especially when you have to keep all the users and devices in mind. So, we have to think out for a simplified and optimized way to create and manage the animations.

Someone said — “Animations give life to the UI components”.

React is a well-established front-end library now and almost everything is possible with it. There are multiple options of doing anything in React and so is the same with animations. We can create animations in React using CSS, JS, or by using an external JavaScript library. But animations can be painful sometimes, so here’s a library named React-Spring, which is highly optimized and simplified for animating React components.

React-Spring is a modern React library based on Spring-physics which is highly flexible and it covers almost all of the UI animation needs. It inherits animated powerful interpolations and performance, as well as React-motion’s ease of use.

Basics of React-Spring

As React-Spring is a modern animation library, it supports both hooks based API and the traditional class-based API as well. The hooks based API is based on 5 kinds of hooks while the class-based API is based on the react-spring components. As the React community is now focussing on functional components for simplicity so we will proceed with the hooks API. These concepts can be interpreted with the class-based API as well because the basics remain the same.

Spring is the basic component of the library and we will use that oftentimes. It acts as a building block of the animations in React-Spring. Spring means a factor that helps a component to move from one point/place to another.

There are 5 major hooks in React-Spring:

  1. useSpring — a single spring that moves data from a → b
  2. useSprings — multiple springs, for lists, where each spring moves data from a → b
  3. useTransition — where we need to mount(add)/unmount(remove) elements transitions
  4. useTrail — multiple springs where one spring trails/follows behind the other.
  5. useChain — to queue or chain multiple animations together.

A Basic Demo

A basic demo of react-spring

Here, we are using the useSpring hook for defining two springs. It is clearly evident that we are taking an object named “from” where the initial value is assigned and a “number” property which signifies the final value. Similarly in the second spring, we are using a “from” object to define the initial value, the opacity property for the final value, and delay property for the delay in animation. Also, we’re using a component defined in react-spring called animated in order to animate our wrapped components.

In this way, the springs also handle other things like CSS properties, colors, absolute lengths, relative lengths, angles, scrolls, HTML attributes, string patterns, and a lot more.

Now that we know the basics of Spring, let’s jump on to some advanced stuff.

An Advanced Demo

import React from "react";
import { useSpring, animated } from "react-spring";
import "../style.css";

const calc = (x, y) => [-(y - window.innerHeight / 2) / 20, (x - window.innerWidth / 2) / 20, 1.1]
const trans = (x, y, s) => `perspective(600px) rotateX(${x}deg) rotateY(${y}deg) scale(${s})`;

const cardContainerStyle = {
  margin: "auto",
  width: "30%",
  marginTop: "15vh"
};

export const UseSpringDemoPage = () => {
  const [props, set] = useSpring(() => ({ xys: [0, 0, 1], config: { mass: 5, tension: 350, friction: 40 } }));
  return (
    <div style={cardContainerStyle}>
      <animated.div
        class="card"
        onMouseMove={({ clientX: x, clientY: y }) => set({ xys: calc(x, y) })}
        onMouseLeave={() => set({ xys: [0, 0, 1] })}
        style={{ transform: props.xys.interpolate(trans) }}
      />
    </div>
  );
};
Code for useSpring demo

In the above code, we are trying to animate a card in 3D so for that, we are taking an array ‘xys’ for the dimensions and a config object for setting some configurations specific to the object we want to animate.

This config property will define how the object will move based on some parameters like mass, tension, friction, etc. Now, in the card, we are using onMouseMove event and onMouseLeave event and in these events, we are calculating the x & y positions of the object. Based on these calculations, we are transforming the object accordingly using the interpolate method of react-spring.

Interpolation, as the name suggests, is the process that takes multiple animation strings and merges them to form a complex animation. In React-Spring, we use the interpolate method to do so.

Going one step further

Now after getting the idea of useSpring, let’s try another react-spring hook called useTransition which helps us to add or remove successive elements. In useTransition hook, we define multiple elements and those elements follow a particular set of animation rules.

import React, { useState, useCallback } from "react";
import { useTransition, animated } from "react-spring";
import "../style.css";

const items = [
  ({ style }) => (
    <animated.div
      style={{
        ...style,
        background:
          "url(https://images.pexels.com/photos/1904769/pexels-photo-1904769.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500) no-repeat"
      }}
    />
  ),
  ({ style }) => (
    <animated.div
      style={{
        ...style,
        background:
          "url(https://images.pexels.com/photos/775201/pexels-photo-775201.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500) no-repeat"
      }}
    />
  ),
  ({ style }) => (
    <animated.div
      style={{
        ...style,
        background:
          "url(https://images.pexels.com/photos/2387866/pexels-photo-2387866.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500) no-repeat"
      }}
    />
  )
];

export const UseTransitionDemoPage = () => {
  const [index, setIndex] = useState(0);
  const onClick = useCallback(
    () => setIndex(state => (state + 1) % items.length),
    []
  );
  const transitions = useTransition(index, p => p, {
    from: { opacity: 0, transform: "translate3d(0, 100%, 0)" },
    enter: { opacity: 1, transform: "translate3d(0, 0%, 0)" },
    leave: { opacity: 0, transform: "translate3d(-50%,0,0)" }
  });

  console.log(transitions);

  return (
    <div className="useTransitionDemoPage">
      <div className="simpleTransitionDemo" onClick={onClick}>
        {transitions.map(({ item, props, key }) => {
          const Page = items[item];
          return <Page key={key} style={props} />;
        })}
      </div>
    </div>
  );
};
Code for useTransition demo

In the above code, we are defining a set of items to render (in our case it’s a set of images) and based on the defined useTransition hook definition we will animate those items. In useTransition hook, we are defining an object and 3 properties viz. from, enter and leave are defined and transformations are mentioned in those properties. The useTransition hook returns an array of object that contains the state like whether the component is entering or leaving or steady.

Now, in order to render and animate the items we will use the map function on transitions array and return the respective elements. In this way, the useTransition hook will be used to create the transition animation in React-Spring.

What's the Final Result?

The Final Words

Animations can be painful sometimes so if we have a simplified approach to create and manage the animations then it becomes easy for the developer to play with them. The React-Spring library is a very good option for simplified yet very beautiful animations for React components.

In this article, we have seen some basic and advanced animations using react-spring with some hooks but you can try out others as well. I hope this article will help you to integrate animations in your next website with React. I would like to thank the react-spring developers' team for the awesome demos shown on their websites, which helped me a lot.

You can find the complete code of this article in the below link:

ritesh-sharma33/react-spring-example
Created with StackBlitz ⚡️. Contribute to ritesh-sharma33/react-spring-example development by creating an account on GitHub.

I appreciate your patience in reading this article. Thank you for reading this article till the end.