Initializing the Project
Let's start the project by creating a Next.js application. We can do that by running npx create-next-app@latest client
inside of a terminal.
- We will use Framer Motion for the animation, so we can run
npm i framer-motion
. - We will use the Lenis Scroll for the smooth scrolling, so we can run
npm i lenis
.
Creating the Base Layout
The first thing to do is to to create the layout, it's just bit of HTML and CSS, nothing too crazy here:
1
export default function Home() {
3
<main className="relative">
We should have something like this:
Making the First Section Sticky
To create the effect, we first need to make the first section sticky, then it's going to be much easier to simply animate the sections. To make the first section sticky, all we have to do is
- Set the parent to a position
relative
with 200vh
of height, since we have two sections that each take 100vh
. - Set the sticky section to
position:sticky
with top:0
.
1
export default function Home() {
3
<main className="relative h-[200vh]">
We should have something like this:
Adding On Scroll Animations
Now that we have our base structure, we can simply add some animation on scroll. To do this, we have to track the progress of the scroll and animate the scale and the rotation value of the sections based on it.
Tracking the Scroll
1
const container = useRef();
2
const { scrollYProgress } = useScroll({
4
offset: ["start start", "end end"]
8
<main ref={container} className="relative h-[200vh]">
9
<Section1 scrollYProgress={scrollYProgress}/>
10
<Section2 scrollYProgress={scrollYProgress}/>
Scaling and Rotating on Scroll
1
const Section1 = ({scrollYProgress}) => {
3
const scale = useTransform(scrollYProgress, [0, 1], [1, 0.8]);
4
const rotate = useTransform(scrollYProgress, [0, 1], [0, -5]);
7
<motion.div style={{scale, rotate}} ...>
- Here I'm using the useTransform hook to transform the scrollProgress into new values that I then use for the scaling and the rotation.
- As you can see here, the only difference between the first section and the second section is the values are reversed.
Adding a Smooth Scroll
To make everything more smooth, we can add a smooth scroll using the Lenis library:
2
const lenis = new Lenis()
6
requestAnimationFrame(raf)
9
requestAnimationFrame(raf)
We should have something like this:
As simple as this!
Quite a simple animation on the technical side, but visually I think it looks stunning and really adds a nice little touch to a website. Hope you learned something!
-Oli