On scroll animations with react framer motion
Add on scroll animations to your react elements with 3 lines of code
Lately I was working on rest countries api and also playing around with react framer motion, Then I found out the most awesome thing ! with framer motions, You can literally add on scroll animation to your elements by 3 lines of codes ๐ฒ
I mean, You can achieve the same thing with Vanilla js too, but it requires some configuration and add some unnecessary complexity to your codebase which becomes pain in the neck over some time. In case you don't like framer motion, You can checkout my Clipboard landing page solution which features on scroll animation with Vanilla js.
Let's get to code
Let's do this ! First I'm gonna explain the project overally, keep in my mind that this approach can be applied to any project you have and It's not limited to what we are going to talk about here.
So, I was building
REST Countries API with color theme switcher
which is an advanced frontend mentor challenge, and I decided to use
react framer motion to spice things up a
little bit. I fetched countries using
restcountries API and looped through them, and for
each country I returned a Card
component ( which we will add on scroll
animation to it later on ). so initially, this is how my Card
component looked
like ๐
import Link from 'next/link'
import s from './styles.module.scss'
export const Card = ({ country }) => {
const { name, population, region, capital, flags, alpha3Code } = country
return (
<div className={s.card}>
<Link href={`/country/${alpha3Code}`}>
<a>
<img className={s.img} src={flags.png} alt={name} />
<div className={s.text}>
<h2 className={s.name}>{name}</h2>
<ul className={s.list}>
<li>
Population : <span>{population.toLocaleString('en-US')}</span>
</li>
<li>
Region : <span>{region}</span>
</li>
<li>
capital : <span>{capital}</span>
</li>
</ul>
</div>
</a>
</Link>
</div>
)
}
This is a really simple component, it receives a country as a prop and display
it's info, and I used scss modules for styling. and this how my homepage looked
like using initial Card
component ๐
This looks really straight forward, and honestly there is nothing wrong without any animations here ! But animations brings more life to our applications and make them feel more interactive. So let's install framer motion by running the following command
npm i framer-motion
after package is installed, refactor the Card
component and add scroll
animation to it ๐
import Link from 'next/link'
import s from './styles.module.scss'
import { motion } from 'framer-motion'
export const Card = ({ country }) => {
const { name, population, region, capital, flags, alpha3Code } = country
return (
<motion.div
className={s.card}
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
>
<Link href={`/country/${alpha3Code}`}>
<a>
<img className={s.img} src={flags.png} alt={name} />
<div className={s.text}>
<h2 className={s.name}>{name}</h2>
<ul className={s.list}>
<li>
Population : <span>{population.toLocaleString('en-US')}</span>
</li>
<li>
Region : <span>{region}</span>
</li>
<li>
capital : <span>{capital}</span>
</li>
</ul>
</div>
</a>
</Link>
</motion.div>
)
}
As you can see, there is not much changes here and we only imported motion
,
and added 2 more lines of codes to our Card's div
, and boom ! let's checkout
our project in the browser ๐
Much better ! as you can see, all the Card
s elements have opacity : 0
as
initial value, as soon as they get inside the viewport, their opacity
becomes
1, and framer motion handles all the complexity for us ! And we are not even
limited to that and we can add more styles, for example we can add scale
too
๐
import Link from 'next/link'
import s from './styles.module.scss'
import { motion } from 'framer-motion'
export const Card = ({ country }) => {
const { name, population, region, capital, flags, alpha3Code } = country
return (
<motion.div
className={s.card}
initial={{ opacity: 0, scale: 0.5 }}
whileInView={{ opacity: 1, scale: 1 }}
>
<Link href={`/country/${alpha3Code}`}>
<a>
<img className={s.img} src={flags.png} alt={name} />
<div className={s.text}>
<h2 className={s.name}>{name}</h2>
<ul className={s.list}>
<li>
Population : <span>{population.toLocaleString('en-US')}</span>
</li>
<li>
Region : <span>{region}</span>
</li>
<li>
capital : <span>{capital}</span>
</li>
</ul>
</div>
</a>
</Link>
</motion.div>
)
}
and the result will be ๐
Now you can do whatever you want and create your own unique and cool animations with framer motion. You can also find the source code here ๐ฅ