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 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 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
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
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 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
Result
I hope this was useful for you :), feel free to check my personal website have a great day Happy Code 🧑🏻💻
Top comments (3)
Nice thanku for this 🔥✌️
Yes exaclty 😄, with a custom hook. Thank you for your comment
happy code 🧑🏻💻
This is what I was looking for. Thanks a lot