Scroll reveal with Framer Motion
Tags: react, javascript, webdev
Published: 2021-08-22 02:01:04

Framer Motion is a library for creating awesome animations on React in an easy and fast way, it let us create simple or complex animation with components and set values like props, we're familiar with React. Something I really like about Framer motion is how we can make animations without expending time creating a CSS file and setting up everything this allows us to create something really awesome in a short period of time.

In this blog I'll show you how u can implement a Scroll reveal animation with framer motion, you'll be surprised how much easy it will be.
> I'll use React-Interception-Observer to control the screen events you can check the [documentation](https://github.com/thebuilder/react-intersection-observer) if you wanna know more.

Of course, you can create a React custom Hook to control the intersection in the screen or also use vanilla js with [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) but in this case, I wanna show a small React library that let us control intersection in react easy and fast.


### Installing necessary libraries
First lets to install the **libraries** for our project
- npm install react-intersection-observer --save
- npm install framer-motion

I'll create a Box component just to animate it and show it while we scroll down, but you can use any component or element for example a card, title, etc...  you have in your application

![https://res.cloudinary.com/elvisdev2280/image/upload/v1629567992/blogs/Screenshot_2021-08-20_at_7.12.30_PM_rvgeo1.png](https://res.cloudinary.com/elvisdev2280/image/upload/v1629568021/Screenshot_2021_08_20_at_7_12_30_PM_rvgeo1_b6183b504b.png)



#### React-Interception-Observer library
Now let's import React-Interception-Observer library to our component taking **useInView** hook

and now we have to use the useInView hook and distructure it like this
const {inView, entry, ref} = useInView();
InView tells us with a false or true when the element is on the screen view, entry is the information between the root and the component is like the different status it has while we scroll down
and ref is for the DOM element we wanna observe

Right now it should look like 
```
import {useInView} from "react-intersection-observer";
const Box = ({text}) => {

  const {inView, entry, ref} = useInView();
  return (
    <div ref={ref}>
    {text} 
    </div>
  )
}
export default Box;
```

### Animation with Framer motion
Then now let's start the animation part, We'll do the next steps
- Import framer motion to our component
- use motion component
- create an initial animation
- use framer motion **useAnimation** hook
- start the animation when **inView** is true

```
import { motion, useAnimation } from "framer-motion";

<div ref={ref}>
    <motion.div
      
      initial={{
        x: "100vw"
      }}
      animate={animationControl}
      className="box"
    >
      {text}
    </motion.div>
    </div>
```
First, we import **motion** and **useAnimation** from our library Framer-motion.
In this case, we have to use a <div> like container to let our website know where's the element we're animating if we don't use a container in our first animation when we use a transformX 100vw it will disappear from our screen view and our website will not know when is the moment to fire the animation because don't find any element with ref in our viewport, then in the <div> container we'll put our ref for following that element.

#### Motion component
motion component lets us create our animation through props, we can create any motion component from HTML labels.
> for example motion.a, motion.div, motion.main, motion.p etc...
We have different props for these components, I invite you to check [documentation](https://www.framer.com/docs/animation/#component-animation-controls) for know more about it.
in this example, we'll use **animate** and **initial**.

#### Motion initial prop
initial is from where we want our component to start to do the animation, in this case, we wanna our component to start from 100vw to make it disappear in the right X corner.
> Tip: check your container that holds all the app elements have a  overflow-x: hidden to avoid your website is broken because the elements are over the screen view waiting to be a fire

#### Motion control animation
well... everything looks fine but how we'll fire our elements because now it disappears and that's not our objective right ?.
Here is where **useAnimation** hook comes to help us, it allows us to start or stop our animation and it's exactly what we're looking for.

first, we need to create a variable for saving the object that comes from the hook
```
 const animationControl = useAnimation();
```
you can use any name u want, this will let us control our animation
and now we can do something simple like this
```
if (inView) {
    animationControl.start({
      x: 0,
      transition: {
        delay: 0.7,
      }
    });
  }
```

this means if **inView** is true (element is on our viewport) then we'll call our control method to start the animation we want, in this case, make the element comeback at x: 0, it means to come back to the initial position where this should be
> I add a delay to 700ms for don't fire it immediately then the user can enjoy more of the animation watching the element completely.

#### Motion animate prop
finally, we have to show or fire the animation, we created a control that will only allow firing the animation when it's in the viewport but to show or run that animation we need to use the animate prop it gets an object with the property we want, in this case, we'll use **animationControl** who have the object we set in the previous step.

the final code should look like
![https://res.cloudinary.com/elvisdev2280/image/upload/v1629534308/blogs/Screenshot_2021-08-20_at_10.39.18_PM_j3paty.png](https://res.cloudinary.com/elvisdev2280/image/upload/v1629534340/Screenshot_2021_08_20_at_10_39_18_PM_j3paty_98927eebbb.png)



### Result

![ezgif.com-gif-maker_pur1ja.gif](https://res.cloudinary.com/elvisdev2280/image/upload/v1629528196/ezgif_com_gif_maker_pur1ja_a15b2812d8.gif)

I hope this was useful for you :), feel free to check my personal [website](https://elvisdev-portfolio.netlify.app/) have a great day Happy Code 🧑🏻‍💻