DEV Community

Cover image for React: Scroll Transition for Fancy Portfolios

Posted on


React: Scroll Transition for Fancy Portfolios

I saw this fancy scrolling effect on this website and it just blew my mind. I thought of recreating it and got somewhat successful :)

BTW, surely check this portfolio website by Ilya Kulbachny.

Read this article on my blog to see it working live and also to get the source code


Run the following commands to have an initial setup to work on.

git clone
cd scroll-transition
git checkout starter
yarn start
Enter fullscreen mode Exit fullscreen mode

Final File Structure

Final File Structure


Let's start with the hero section. We'll be using framer-motion to animate the image on scroll.

Copy paste this code in src/components/heroSection.js

import React from 'react';
// 1.
import { motion, useViewportScroll, useTransform } from 'framer-motion';

import styles from '../styles/heroSection.module.css';
import heroImage from '../assets/images/5.jpeg';

export default function HeroSection({ offset = 1500 }) {
  // 2.
  const { scrollY } = useViewportScroll();
  // 3.
  const scale = useTransform(scrollY, [0, offset], [1, 5]);
  const opacity = useTransform(scrollY, [0, offset], [3, 0]);
  const moveDown = useTransform(scrollY, [0, offset], [0, -1000]);

  return (
      <div className={styles.imageContainer}>
        {/* 4. */}
            opacity: opacity,
            scale: scale,
            y: moveDown,
      {/* 5. */}
      <div style={{ background: '#030303', height: `${offset}px` }}></div>
      <div style={{ background: '#030303', height: '80vh' }}></div>
Enter fullscreen mode Exit fullscreen mode

Let's break it down:

  1. Here we import all the sass we need from framer motion
    1. motion: Grants a normal JSX element super powers (extra props to work with framer motion API)
    2. useViewportScroll: Can be used to track the position of the scroll.
    3. useTransform: Can be used to change the value of a variable based on a changing value of another variable. (by default: the change is linear)
  2. We are using the useViewportScroll hook to get the vertical scroll distance in pixels
  3. Using the useTransform hook to change the value of 3 variables, scale, opacity, and moveDown based on the scrollY
  4. Here we pass the dynamic values to the styles prop of the motion component.
  5. Lastly, we are adding this empty div of height equal to the total scrolling area we set. This allows us to scroll as the above imageContainer is set toposition: fixed

Thank you for reading!

Read this article on my blog to see it working live and also to get the source code

Top comments (2)

ayomiku222 profile image
ayomiku olatunji

Good... Thanks for this

holdmypotion profile image

Your welcome!

Visualizing Promises and Async/Await 🤓

async await

☝️ Check out this all-time classic DEV post on visualizing Promises and Async/Await 🤓