Skip to content

Instantly share code, notes, and snippets.

@christiannwamba
Created May 30, 2018 14:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christiannwamba/225a87f261edd07ae762d14d86645b42 to your computer and use it in GitHub Desktop.
Save christiannwamba/225a87f261edd07ae762d14d86645b42 to your computer and use it in GitHub Desktop.

5 React Motion Use Cases With Examples

Introduction

React-motion is a creditable library that makes it easy to create realistic animations within components using laws of physics. An endless possibilities of realistic animations can be explored by simply specifying values for stiffness and dampness within one of the exported components.

At first, these terms might not make so much sense to a person who’s just learning about this library, but at the end of this article, we will have discussed the meaning of these terms and looked at several use-cases where this library will prove applicable.

Prerequisites

To follow along with the flow of this article, it is necessary that you have these tools installed on your computer:

  1. Node and npm
  2. Create-react-app (npm install -g create-react-app)

We will be showing all the use cases using the create-react-app tool.

Since this article focuses on showing how to use the react-motion library in React projects, it is assumed that the reader has at least a basic knowledge of React and a general understanding of JavaScript.

By the end of this article, we will have created several simple animation projects including this animated jumbotron revealer:

A Brief Overview

Before we start writing code and exploring any use-cases, it is imperative that we first discuss some of the basic properties of the react-motion library, so we understand it to a significant extent.

React motion exports three main components: Motion, StaggeredMotion and TransitionMotion.

Throughout this article, we will be working with the Motion component and we will see how to import it into our development environment and design creative animations. The kind of animations we will be making are called spring animations because they start at a defined value and spring towards the destination value.

Besides the start and finish values we just discussed, there are two other values we will be setting when creating animations. These values (variables) are: stiffness and damping. When starting out with creating these animations, it might not be visible what impact changing these values bring about, but these variables control the overall feel and structure of each animation.

That being said, let’s briefly define them below:

Stiffness defines how forcefully the object in an animation is pulled towards its final value.

Damping is the simulated friction the object will be subject to as it approaches its target.

Tweaking these values can bring about an overwhelming or subtle change to the entire animation.

Now that we have defined these terms, we can proceed to building a few projects to demonstrate relatable use-cases.

1. Hamburger Menu

The first project we will be integrating react-motion into is a hamburger menu. This project isn’t difficult to build at all and can be built without writing a single line of JavaScript code. However, this tutorial aims at demonstrating how components can easily be animated in React.

Let’s begin by creating a new project using the create-react-app tool:

https://gist.github.com/6b455339705402f3459544d7d0aaa057

Now let’s navigate into the newly created directory and pull in the dependencies we need:

https://gist.github.com/121067c13a070bded937068100ada967

We are installing react-motion because we need it to animate the movement of the side section that swings into the screen when the drawer is clicked upon.

We need styled``-``components to create styled components within our application. Another perk with creating a styled component is that we are able to easily use props values from that component while styling, this already creates an infinite possibilities in animation since we can dynamically use the values of props to update the style of that component.

Let’s update the App.js file, we will import the styled components package and use it to create a Wrapper component. Lastly, we will render the Wrapper component and a Hamburger component that we are yet to define:

https://gist.github.com/f75f86f0388358ea6d60f7a0707944d1

Neatly done! Now let’s create a Hamburger.js file in the src directory:

https://gist.github.com/c8675c8ae9643372beb105bc0448ad16

In the Hamburger.js file, let’s start laying out the general structure, we will start by importing the styled-components and react``-``motion packages. We also want to create two components using the styled components package. These components are Drawer and Links, the former will be the drawer section that slides into the focal region of the screen when we click the hamburger icon, while the latter will hold the links on the Drawer:

https://gist.github.com/c374ff7236e09d2dd9611f9bbc96c972

You might have noticed that we wrote ${(props) *=>* props``*.*``left}vh while writing the styles for the Drawer component, we did this so that the value of the left property can be dynamic and updated as it updates in the component.

Now we can move further to defining and exporting the Hamburger component. Within the Hamburger component, we want to register a constructor and call the super() function. We also register a single state toggleState which we will use to keep track of the state of the hamburger menu at any time. We will also include a method to handle the clicks on the hamburger icon.

https://gist.github.com/40ad466f3753e4b8f325ef00b93e7075

Now in the render function, we will write some JSX code to define the structure of the application on the DOM. For the best part, we will register a Motion component from the react motion library. The Motion component adopts the render prop pattern so it accepts some props and a function as its children and we pass in our Drawer component to that function:

https://gist.github.com/629b89a35c697fcdb65af53ea67085f4

It can be observed from the code above that in the Motion component, we set an optional defaultStyle to *left*``: -40 and then we set the style to this long expression: *left*``: spring(``*this.*``state``*.*``toggleState ? 0 : -40, {``*stiffness*``: 210, *damping*``: 10} )

What these two expressions mean are:

By default, set the left property (that automatically updates within the styled component) of this component to -40vh.

If the toggleState variable is set, then animate the component from its current left value (-40vh) to one of 0vh while applying a stiffness of 210 and a damping of 10. However, when it isn’t set, let it continue being equals to -40 (hence no animation)

We can run this application now to see just what we’ve built but we might be startled by the hideousness of its look! Let’s ass some CSS to the App.css file to give it a nice look:

https://gist.github.com/6a277be137ca8794ea08d8322e153298

Awesome stuff! We can run the application now by typing this command in the root directory of the project:

https://gist.github.com/f55af48c293d65e050e98f31e9ae5561

We will point our browser to http://localhost:3000 and get this screen:

The source code for this project is available here on GitHub.

2. Preloader

Under this section, we will simulate the spinning of a preloader when some other action is running and needs time to complete before the user can get output. However, this is just a simulation so we wouldn’t tie the spinner to any larger application or process. We begin.

We can create a new application with this command:

https://gist.github.com/374bb241a6d50f21668d0028519be7b0

Let’s navigate into the working directory and install dependencies using these commands:

https://gist.github.com/3d98e833f31ee6304c99e5d1032c4150

We will be using styled-components in all of our projects because it makes everything easier.

Now we want to update the App.js file, we will import the styled components package and use it to create a Wrapper component. Lastly, we will render the Wrapper component and a Preloader component that we are yet to define:

https://gist.github.com/f3c079107aa470e81a50317fb30a776c

We also need to give our application some information on how to reference the bootstrap package that we just pulled in, so we open the index.js file and include this line to the list of imports *import* '``*../node_modules/bootstrap/dist/css/bootstrap.min.css*``' so it looks like this:

https://gist.github.com/77cd8888d8df78ca1dc5d25838773a99

We will create the Preloader.js file in the src directory:

https://gist.github.com/12799235d5416186afced181b5cfc959

In the Preloader.js file, let’s start laying out the general structure, we will start by importing the styled-components and react``-``motion packages. We also want to create a component — Loader — using the styled components package. This components will be the actual loader/spinner:

https://gist.github.com/233f52e8cae14082f18a177c15c2ff02

We wrote ${(props) *=>* props``*.*``transform}deg while writing the styles for the Loader component, we did this so that the value of the transform property can be dynamic and updated as it updates in the component itself.

Now we can move further to defining and exporting the Preloader component. Within the Preloader component, we want to register a constructor and call the super() function. We also register a two state variables:

  1. startLoader
  2. numberOfSpins

The application will use the startLoader in deciding when to start the Loader, while the numberOfSpins determines how many full circles the spinner does, for this project, we will set it to 5 by multiplying 360 by 5. Lastly we will include a simple function to switch the value of startLoader from 0 to 1 to indicate that it should start the spinner on the click of a button:

https://gist.github.com/cfc4792f318347210aa15ef947991aaa

Now in the render function, we will write some JSX code to define the structure of the application on the DOM. We will register a Motion component from the react``-``motion library. The Motion accepts some props and a function as its children and we pass in the Loader component to that function:

https://gist.github.com/89b89e06c2298b6052e08bdfd913a5b1

The magic of this application lies in the section where we set an optimal defaultStle to *transform*``: 0 and then set style to *transform*``: spring(``*this.*``state``*.*``startLoader ? *this.*``state``*.*``numberOfSpins: 0, {``*stiffness*``: 10, *damping*``: 10}).

In very basic terms, what these mean are:

set the default property of the transform property (that is bound to the Loader component) to 0

Whenever the startLoader state variable is set, do a transform to the set number of spins.

Before we run this application, we need to include some styles in the App.css file:

https://gist.github.com/00a28d6e36624bef521e58922dadeb6a

We can run the application now by typing this command in the root directory of the project:

https://gist.github.com/3522c52f70d7f231ab18e7dba937cfc6

We will point our browser to http://localhost:3000 and get this screen:

Note: The spinner spins this way because we have set the stiffness and dampness to 10, you can tweak the animation to your taste by understanding the behavior of the stiffness and dampness properties from the earlier discussion and updating them adequately.

The source code for this project is available here on GitHub.

3. Progress Bar

There’s hardly a person who has been on a mobile smart-phone or computer that would say he/she hasn’t seen a progress bar before. Progress bars are very important because they can communicate the status of a process to a user by showing the current length of the progress against the full-length of the bar. Let’s build our own simple progress bar using react motion:

https://gist.github.com/45cf0df48f0fe15cf39d855d630ac1b3

Let’s navigate into the working directory and install dependencies using these commands:

https://gist.github.com/1c9da9c1973ea152a7a03d9dab2b4005

Now we want to update the App.js file, we will import the styled components package and use it to create a Wrapper component. Lastly, we will render the Wrapper component and a Progresscomponent that we are yet to define:

https://gist.github.com/d77239bafa0289fa14f14e4b1280e38f

We also need to give our application some information on how to reference the bootstrap package that we just pulled in, so we open the index.js file and include this line to the list of imports *import* '``*../node_modules/bootstrap/dist/css/bootstrap.min.css*``' so it looks like this:

https://gist.github.com/b86f80eef8b8b857f4a1794e2d85cede

We will go further and create the Progress.js file in the src directory:

https://gist.github.com/1458c6560c934dc632fc25ea8488bf4c

In the Progress.js file, we will start by importing the styled-components and react motion packages. We also want to create a component — ProgressBar — using the styled components package. This component will be the actual ProgressBar, we will start the progress bar based on the state of a startProgress state variable. We’d also set the stiffness and damping of the Motion component to 10:

https://gist.github.com/3966618aa855acb18bec1044d68a9397

We used the Math.trunc function here to return the springed width as an integer by removing the fractional digits.

Before we run this application, let’s add these styles to the App.css file:

https://gist.github.com/d3b128615e626b3740b8fc78e23cab3b

We can run the application now by typing this command in the root directory of the project:

https://gist.github.com/5912dc1398f85ce5ae302132db384e19

We will point our browser to http://localhost:3000 and get this screen:

The source code for this project is available here on GitHub.

4. Animated Notification

What’s better than being notified about the last interaction between a user and an application? You guessed it right! Being notified with a sliding animated notification in realtime. We will build a small login system that takes in a username and password then notifies the user on the status of his validation when he clicks on the Sign in button.

https://gist.github.com/aa9653cb6f81a9a09ff938cce6d67b84

Let’s navigate into the working directory and install dependencies using these commands:

https://gist.github.com/55ad12ff56f8ecfd57461065ef97341f

Now we want to update the App.js file, we will import the styled components package and use it to create a Wrapper component. Lastly, we will render the Wrapper component and a Form component that we are yet to define:

https://gist.github.com/05b5f334c414eb9de86125c8f81d28f1

We also need to give our application some information on how to reference the bootstrap package that we just pulled in, so we open the index.js file and include this line to the list of imports *import* '``*../node_modules/bootstrap/dist/css/bootstrap.min.css*``' so it looks like this:

https://gist.github.com/362dabae4f1bd47aa0ee0ed9ca9132f5

Now let’s create a Form.js file in the src directory:

https://gist.github.com/08df28b18f7f6cc41b1d2acad032b7cb

In the Form.js file, we will start by importing the styled-components and react motion packages. We will define a single component using styled component, this component would be called NotificationBox. We will register a state — startAnimation — that will decide when the animation starts and we will register two functions:

  1. handleClick — This function will handle click events on the ‘sign up’ button and call the other function so it resets the state of startAnimation to 1
  2. resetValue — This function will reset the state of the startAnimation variable.

https://gist.github.com/17135efdf487a474a69f3e58df3b246d

Within the render function, we write some JSX code that defines the structure of the form then we register a Motion component to animate the NotificationBox component:

https://gist.github.com/92c884d17617188695f96d68f57fc8b0

As before, we have bound top and opacity properties of the component with it’s style so we get nice animations when the submit button is clicked. Let’s add the styles to the App.css file:

https://gist.github.com/db10dcee5fde24d8cf41cd233d575fc5

We can run the application now by typing this command in the root directory of the project:

https://gist.github.com/9c977d4cc2b076ceba7f0dabd29d50e7

We will point our browser to http://localhost:3000 and get this screen:

The source code for this project is available here on GitHub.

5. Animated Jumbotron Revealer

We’ve looked at some basic examples so far, but now we’d look at something more complex, we are going to create an animated “jumbotron revealer.” In simpler terms, this is an application that displays a black screen on initial load then gradually reveals the jumbotron using react motion. Let’s get started.

We will create a new project:

https://gist.github.com/1f0904ee6fce4fbbcdad5cff5b38820d

We can navigate into this directory and install the dependencies:

https://gist.github.com/a6d12e1b7ab560716f36466dc73bce6e

Let’s make a quick edit to the App.js file, we want to import styled-components and also import ImageBoxAnimation (which is a component we’d create very soon):

https://gist.github.com/246be0aac0f5e5b2f4d2f4d4df107306

We need to create two separate files for two components so let’s navigate into the src directory and create them:

https://gist.github.com/6656772a38ceb53b611615f568cbb865

Awesome! Now let’s open up the ImageBoxAnimated.js file in our favorite editor and begin writing some code, the first thing we want to do is import the dependencies and the BlackBoxAnimated component (though the file is currently empty) then create a new component using the styled components. The ImageBox component will basically be a div that loads a picture as its background image from the internet:

https://gist.github.com/128d7455863f8b7d333c7a58b81ef7bf

The next thing we will do is create the ImageBoxAnimation component and set a single state variable — animationNumber — we need this state variable to decide when the black boxes that will initially cover the jumbotron will start to slide away.

We will also define a function — startNextAnimation — which serves the purpose of augmenting the animationNumber that decides which box slides.

We will use the setTimeout() function to call the startNextAnimation function that increments the animationNumber. Whenever a timeout runs, a new black box will slide (there will be about 10 of them by the completion of this project) across the jumbotron’s image.

In the render function, we will start by initializing an object { animationNumber } to our application’s current state so that we can refer to it directly within the render function without having to call this.

Next, we will register 10 instances of the BlackBoxAnimated component and pass down three props to each one of them, these props are:

heightPercentage — This props is responsible for setting the height of each black box relative to the total height of the jumbotron. We will set it to 10% so that we have space for exactly 10 boxes

reverseDirection — This props takes a boolean value to decide in which direction the box should slide, because if all the boxes slide in one direction, then it would be visually boring. We will alternate between truth and false to give it a zigzag feel.

startAnimation — This props is very important because it is responsible for the cascading behaviour of the animation. It makes sure that the black boxes leave one at a time (because the setTimeout function gives a space of half a second before calling the setNextAnimation function which is responsible for increasing the value of animationNumber by 1) by comparing its value against a number and returning a boolean value to the BlackBoxAnimated component. A false does nothing while a true starts the animation.

Finally, we will export the application:

https://gist.github.com/3344d87f1dbca17fbc154447edd97f7b

Now that that’s done, let’s open the BlackBoxAnimated.js file we created a while ago and prepare it for the data that is being passed down by ImageBox. We will start by importing the dependencies we’ll need, but this time we will also import PropTypes *from* '``*prop-types*``' and this would help us confirm that our props are what we want them to be when they are being received. We will also define a Blackbox component using styled components and populate it with some styles:

https://gist.github.com/12ef6ca0703c26d596020968d8daf7e5

We are using ${(props) *=>* props``*.*``heightPercentage}% and ${(props) *=>* props``*.*``xDirection} center because we want to bind these props from the component with the style properties.

Next, we will create the BlackBoxAnimated component (you can define a component as a function in React) and define the props it should expect. We will register the Motion component and trigger the animation only when startAnimation has the value if true. Lastly, we will check that the props we received in the component are of the type we expected:

https://gist.github.com/11bb8f9c1fc2fdf0ec9d216fbbd22bac

Great, we can run the application now by typing this command in the root directory of the project:

https://gist.github.com/1c43023590c6b4149a3d54be00aab35a

We will point our browser to http://localhost:3000 and get this screen:

The source code for this project is available here on GitHub.

Conclusion

In this article, we have seen how to use react motion to create easy to tweak animations with React components, we have also come to understand the ideas behind the stiffness and damping variables that are available to us when using the library. Though the examples we have looked at in this tutorial mainly covered the basic sides to the library, but it’s a good start for anyone who hopes to build really complex and nice looking web animations with components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment