Written by Gaurav Singhal✏️
React Motion is an animation library for React applications that makes it easy to create and implement realistic animations. In this guide, we’ll demonstrate how to install the library and share some basic tips to help you build natural-looking, physics-based animations for your React projects.
Installing React Motion
Create a new React project by running:
npx create-react-app intro-react-motion
To install React Motion, run the following command inside your project root.
npm i react-motion
Understanding the exports
The react-motion
library exports the following.
-
spring
— A helper function that dictates how the component animates -
presets
— An object of predefined animation properties -
Motion
— A component that is used to animate a component -
StaggeredMotion
— A component that is used to animate components whose animation depends on each other -
TransitionMotion
— A component that is used to animate the mount and unmounts of components
For the sake of brevity, this guide will focus on spring
, presets
, and Motion
.
Helpers: spring()
and presets
The spring()
helper function defines how to animate from the initial style value to the destination value. It takes in two arguments: the value and an option animation config parameter.
For example, spring(10, { stiffness: 130, damping: 42 })
animates the value to 10 with a stiffness of 130 and damping of 42. stiffness
and damping
are animation properties that define the animation’s behavior. Don’t worry — it’s normal not to understand how these properties work.
The presets
properties are used as the animation configuration. For example, spring(25, presets.wobbly)
. Other preset values include presets.gentle
, presets.noWobble
, presets.stiff
.
The <Motion />
component
The <Motion />
component takes in two props: defaultStyle
and style
. The defaultStyle
prop defines the initial values of the style object. The style
prop is an object that defines the style values at any given point. The values of the style
prop are determined using the spring()
helper function. If the defaultStyle
is the original style, then style
is the final style that the components animate to.
The <Motion />
component expects a function as its child prop, which means it uses the render prop pattern. The function receives an interpolated style object, which contains the style value at any given time until the animation is completed.
<<Motion
defaultStyle={{
scale: 0,
translateX: -300
}}
style={{
scale: spring(1),
translateX: spring(0, presets.stiff)
}}
>
{interpolatesStyles => <>{/* React Component */}</>}
</Motion>
React Motion in action
Let’s look at a basic example.
At the top of your component file, import Motion
, spring
, and presets
from the react-motion
library to use them in your component.
import { Motion, spring, presets } from "react-motion";
Create an <h1>
element in the component that will be animated inside App.js
.
// ...
function App() {
return (
<div className="App">
<div>
<h1>Basic Animation Example</h1>
</div>
</div>
);
}
// ...
Now wrap your component with the <Motion />
component and return the <h1>
component from the render prop function. Pass { opacity: 0, translateY: 30 }
in the defaultStyle
prop. In the style
prop, use the spring()
helper function to interpolate the style values.
// ...
<Motion
defaultStyle={{
opacity: 0,
translateY: 30
}}
style={{
opacity: spring(1),
translateY: spring(0, presets.wobbly)
}}
>
{interpolatedStyles => (
<div
style={{
transform: `translateY(${interpolatedStyles.translateY}px)`,
opacity: interpolatedStyles.opacity
}}
>
<h1>Basic Animation Example</h1>
</div>
)}
</Motion>
// ...
Here’s the final code:
import React from "react";
import "./styles.css";
import { Motion, spring, presets } from "react-motion";
function App() {
return (
<div className="App">
<Motion
defaultStyle={{
opacity: 0,
translateY: 30
}}
style={{
opacity: spring(1),
translateY: spring(0, presets.wobbly)
}}
>
{interpolatedStyles => (
<div
style={{
transform: `translateY(${interpolatedStyles.translateY}px)`,
opacity: interpolatedStyles.opacity
}}
>
<h1>Basic Animation Example</h1>
</div>
)}
</Motion>
</div>
);
}
export default App;
Run the following command to see the above code in action.
npm start
The animation will start as soon as the component mounts on to the DOM. Now let’s see how you can also trigger the animation with a button click.
Triggering animation using a button
Using state, you can add style dynamically to interpolate the style values. In a variable, store the initial style for the animation.
function App() {
const [startAnimation, setAnimation] = useState(false);
const initialStyle = { opacity: 0, translateY: 30 };
// ...
}
In the <Motion />
component, you don’t have to specify the defaultStyle
prop because the style
prop is going to change dynamically.
// ...
<Motion
style={
startAnimation
? {
opacity: spring(1),
translateY: spring(0, presets.wobbly)
}
: initialStyle
}
>
{interpolatedStyles => (
<div
style={{
transform: `translateY(${interpolatedStyles.translateY}px)`,
opacity: interpolatedStyles.opacity
}}
>
<h1>Triggered Animation</h1>
</div>
)}
</Motion>
// ...
Add two buttons: one to trigger the animation and another to reset the animation.
// ...
<button onClick={() => setAnimation(true)}>Trigger Animation</button>
<button onClick={() => setAnimation(false)}>Reset Animation</button>
// ...
When the startAnimation
state is set to true
, the style
prop will get the initial style values. When it sets to false
, the style
prop will have the final values.
Your App.js
should look as follows.
import React, { useState } from "react";
import "./styles.css";
import { Motion, spring, presets } from "react-motion";
export default function App() {
const [startAnimation, setAnimation] = useState(false);
const initialStyle = { opacity: 0, translateY: 30 };
return (
<div className="App">
<Motion
style={
startAnimation
? {
opacity: spring(1),
translateY: spring(0, presets.wobbly)
}
: initialStyle
}
>
{interpolatedStyles => (
<div
style={{
transform: `translateY(${interpolatedStyles.translateY}px)`,
opacity: interpolatedStyles.opacity
}}
>
<h1>Triggered Animation</h1>
</div>
)}
</Motion>
<button onClick={() => setAnimation(true)}>Trigger Animation</button>
<button onClick={() => setAnimation(false)}>Reset Animation</button>
</div>
);
}
Using React Motion with styled-components
You can use react-motion
with any other UI library for React. Let’s see how you can use react-motion
with the styled-components
library.
Install styled-components
by running the following command inside your project root.
npm i styled-components
Create the styled <Title />
component as follows.
// ..
import styled from "styled-components";
const Title = styled.h1`
color: #007bff;
font-size: 32px;
${props =>
`transform: translateY(${props.translateY}px);
opacity: ${props.opacity};
`}
`;
// ..
Similar to the above examples, return the <Title />
component from the render prop function. Pass the interpolated values as props to the <Title />
component.
<Motion
style={
startAnimation
? {
opacity: spring(1),
translateY: spring(0, presets.wobbly)
}
: initialStyle
}
>
{interpolatedStyles => (
<Title
opacity={interpolatedStyles.opacity}
translateY={interpolatedStyles.translateY}
>
Triggered Animation
</Title>
)}
</Motion>
Your complete App.js
should look as follows.
import React, { useState } from "react";
import "./styles.css";
import { Motion, spring, presets } from "react-motion";
import styled from "styled-components";
const Title = styled.h1`
color: #007bff;
font-size: 32px;
${props =>
`transform: translateY(${props.translateY}px);
opacity: ${props.opacity};
`}
`;
export default function App() {
const [startAnimation, setAnimation] = useState(false);
const initialStyle = { opacity: 0, translateY: 30 };
return (
<div className="App">
<Motion
style={
startAnimation
? {
opacity: spring(1),
translateY: spring(0, presets.wobbly)
}
: initialStyle
}
>
{interpolatedStyles => (
<Title
opacity={interpolatedStyles.opacity}
translateY={interpolatedStyles.translateY}
>
Triggered Animation
</Title>
)}
</Motion>
<button onClick={() => setAnimation(true)}>Trigger Animation</button>
<button onClick={() => setAnimation(false)}>Reset Animation</button>
</div>
);
}
Regardless of which library you are using, react-motion
will work as long as the library supports custom styling.
If you encounter errors, depreciated warnings, or things that don’t run as expected, revert to the original versions of these libraries by replacing your dependencies inside package.json
file with the following versions.
//...
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-motion": "^0.5.2",
"react-scripts": "3.4.0",
"styled-components": "^5.0.1"
}
//...
Then run:
npm i
This will install the exact same dependencies on which these examples were tested.
Conclusion
React Motion is one of the easiest animation libraries out there for animating components in React. This was just a brief introduction to the react-motion
library. As a next step, I would recommend looking into components such as <StaggeredMotion />
and <TransitionMotion />
, which are similar to the <Motion />
component but have an advanced implementation for more complex animations.
Full visibility into production React apps
Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.
LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your React apps — start monitoring for free.
The post Introduction to React Motion appeared first on LogRocket Blog.
Top comments (0)