profile picture of Olivier Larose

Olivier Larose

May 13, 2024

/

Beginner

/

Short

Perspective Section Transition

How to make a Smooth Parallax Section Transition with React and Framer Motion

A website tutorial featuring a perspective transition animation with a smooth scroll using React, Framer Motion, Next.js and Lenis Scroll. Inspired by https://www.joinflowparty.com/

Live DemoSource code
background video

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:

Page.js

Section1

Section2

1

export default function Home() {

2

return (

3

<main className="relative">

4

<Section1 />

5

<Section2 />

6

</main>

7

);

8

}

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.

Page.js

Section1

1

export default function Home() {

2

return (

3

<main className="relative h-[200vh]">

4

...

5

</main>

6

);

7

}

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

Page.js

1

const container = useRef();

2

const { scrollYProgress } = useScroll({

3

target: container,

4

offset: ["start start", "end end"]

5

})

6

7

return (

8

<main ref={container} className="relative h-[200vh]">

9

<Section1 scrollYProgress={scrollYProgress}/>

10

<Section2 scrollYProgress={scrollYProgress}/>

11

</main>

12

);

13

}

Scaling and Rotating on Scroll

Section1

Section2

1

const Section1 = ({scrollYProgress}) => {

2

3

const scale = useTransform(scrollYProgress, [0, 1], [1, 0.8]);

4

const rotate = useTransform(scrollYProgress, [0, 1], [0, -5]);

5

6

return (

7

<motion.div style={{scale, rotate}} ...>

8

...

9

</motion.div>

10

)

11

}
  • 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:

Page.js

1

useEffect( () => {

2

const lenis = new Lenis()

3

4

function raf(time) {

5

lenis.raf(time)

6

requestAnimationFrame(raf)

7

}

8

9

requestAnimationFrame(raf)

10

}, [])

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

Related Animations

image

June 2, 2024

Mask Section Transition

A website tutorial featuring a scroll animation using an SVG Mask to create a section transition, made with React, Framer Motion. Inspired by: https://axelvanhessche.com/. Pictures by Eric Asamoah, Inka and Niclas Lindergård, Daniel Ribar

image

May 25, 2024

Background Image Parallax

A website animation featuring a background image moving on scroll in a parallax motion, made with Framer Motion and React, inside a Next.js app. Inspired by: https://inkfishnyc.com/. Pictures by Matthias Leidinger

image

May 25, 2024

Text Parallax

A website animation featuring a Text Parallax with sliding text on scroll, made with Framer Motion and React, inside a Next.js app