Creating Parallax Effects in React

Loading

A parallax effect is a visual effect where the background or elements move at different speeds compared to the foreground, creating a sense of depth and immersion. This effect is commonly used in websites and apps to enhance user experience and engagement. In React, we can easily implement parallax scrolling with libraries like React Spring, Framer Motion, or by using the built-in scroll event to manipulate the position of elements as the user scrolls.

In this guide, we’ll walk through how to create parallax effects in React using React Spring.

1. Setting Up the Project

If you haven’t set up a React project yet, you can create one using:

npx create-react-app parallax-effect
cd parallax-effect

Next, install React Spring:

npm install @react-spring/web

2. Basic Parallax Effect with React Spring

We’ll start with a simple parallax effect where the background moves slower than the content as the user scrolls down the page.

Example: Simple Parallax Effect

import React, { useState, useEffect } from 'react';
import { useSpring, animated } from '@react-spring/web';

const ParallaxEffect = () => {
  const [scrollY, setScrollY] = useState(0);

  // Update scroll position on scroll
  useEffect(() => {
    const handleScroll = () => {
      setScrollY(window.scrollY);
    };

    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  // Create a spring animation for the parallax effect
  const parallaxStyle = useSpring({
    transform: `translateY(${scrollY * 0.3}px)`, // The parallax speed is controlled by the multiplier (0.3)
    config: { tension: 170, friction: 26 },
  });

  return (
    <div style={{ height: '200vh' }}> {/* Make the page tall to allow scrolling */}
      <animated.div style={parallaxStyle} className="parallax-bg">
        <h1 style={{ textAlign: 'center', color: '#fff' }}>Welcome to the Parallax Effect!</h1>
      </animated.div>

      <div className="content">
        <p>Scroll down to see the parallax effect in action.</p>
      </div>
    </div>
  );
};

export default ParallaxEffect;

Explanation:

  • scrollY: Tracks the vertical scroll position.
  • useEffect: Listens for the scroll event and updates the scroll position.
  • useSpring: Animates the background using a translateY property, which moves the background vertically based on the scroll position. The speed of the parallax effect is determined by the multiplier (0.3 in this case).
  • animated.div: This element is animated using the styles returned by the useSpring hook.

Styling (CSS)

/* App.css */
.parallax-bg {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  background-image: url('https://source.unsplash.com/random');
  background-size: cover;
  background-position: center;
  z-index: -1;
}

.content {
  position: relative;
  z-index: 1;
  padding: 100px 20px;
  text-align: center;
}

3. Parallax Effect with Multiple Layers

For more complex parallax effects, you can layer multiple elements, each with its own speed of movement, to create a deeper, more immersive effect.

Example: Multiple Layers with Different Parallax Speeds

import React, { useState, useEffect } from 'react';
import { useSpring, animated } from '@react-spring/web';

const MultiLayerParallax = () => {
  const [scrollY, setScrollY] = useState(0);

  useEffect(() => {
    const handleScroll = () => {
      setScrollY(window.scrollY);
    };

    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  // Parallax styles for each layer
  const layer1Style = useSpring({
    transform: `translateY(${scrollY * 0.2}px)`,
  });

  const layer2Style = useSpring({
    transform: `translateY(${scrollY * 0.4}px)`,
  });

  const layer3Style = useSpring({
    transform: `translateY(${scrollY * 0.6}px)`,
  });

  return (
    <div style={{ height: '300vh' }}>
      {/* Parallax Layer 1 */}
      <animated.div style={layer1Style} className="layer-1">
        <h1>Layer 1</h1>
      </animated.div>

      {/* Parallax Layer 2 */}
      <animated.div style={layer2Style} className="layer-2">
        <h1>Layer 2</h1>
      </animated.div>

      {/* Parallax Layer 3 */}
      <animated.div style={layer3Style} className="layer-3">
        <h1>Layer 3</h1>
      </animated.div>

      <div className="content">
        <p>Scroll down to see different layers moving at different speeds.</p>
      </div>
    </div>
  );
};

export default MultiLayerParallax;

Explanation:

  • Multiple Layers: Here, we have three layers, each with a different parallax speed. The first layer moves at 20% of the scroll speed, the second at 40%, and the third at 60%.
  • useSpring for Each Layer: Each layer has its own spring animation, creating the layered parallax effect.

Styling (CSS)

/* App.css */
.layer-1,
.layer-2,
.layer-3 {
  position: fixed;
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-size: 3rem;
}

.layer-1 {
  background-color: rgba(255, 99, 71, 0.6);
  z-index: -3;
}

.layer-2 {
  background-color: rgba(60, 179, 113, 0.6);
  z-index: -2;
}

.layer-3 {
  background-color: rgba(70, 130, 180, 0.6);
  z-index: -1;
}

.content {
  position: relative;
  z-index: 1;
  padding: 100px 20px;
  text-align: center;
}

4. Parallax Effect with Image and Text Elements

You can also apply the parallax effect to individual text or image elements to create unique scrolling effects.

Example: Parallax Effect with Image and Text

import React, { useState, useEffect } from 'react';
import { useSpring, animated } from '@react-spring/web';

const ImageTextParallax = () => {
  const [scrollY, setScrollY] = useState(0);

  useEffect(() => {
    const handleScroll = () => {
      setScrollY(window.scrollY);
    };

    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  // Parallax animation for the image
  const imageStyle = useSpring({
    transform: `translateY(${scrollY * 0.5}px)`,
  });

  // Parallax animation for the text
  const textStyle = useSpring({
    transform: `translateY(${scrollY * 0.2}px)`,
  });

  return (
    <div style={{ height: '200vh' }}>
      <animated.div style={imageStyle} className="parallax-image">
        <img src="https://source.unsplash.com/random/800x600" alt="Parallax" />
      </animated.div>

      <animated.div style={textStyle} className="parallax-text">
        <h1>Beautiful Parallax Effect!</h1>
        <p>Scroll to see the parallax effect in action.</p>
      </animated.div>
    </div>
  );
};

export default ImageTextParallax;

Explanation:

  • Image and Text Animations: The background image and text have different parallax speeds, giving the illusion of depth.
  • useSpring for Each Element: We animate both the image and the text using separate spring animations to control their movement.

Styling (CSS)

/* App.css */
.parallax-image img {
  width: 100%;
  height: auto;
  object-fit: cover;
}

.parallax-text {
  position: relative;
  z-index: 1;
  padding: 100px;
  color: white;
  text-align: center;
}

Leave a Reply

Your email address will not be published. Required fields are marked *