Get Back
November 24, 2024
Horizontal scroll section using Framer Motion
tricks

In this blog post, we'll walk through the process of creating a visually appealing scrollable image gallery using React and Framer Motion. The gallery will feature a horizontal scroll effect that responds to vertical scrolling, allowing users to navigate through a collection of images seamlessly.

Setting Up the Project

First, ensure that you have a React environment set up. You can use tools like Create React App to quickly bootstrap your project. Install Framer Motion by running the following command in your terminal:

npm install framer-motion

This library will help us create smooth animations and transitions in our gallery.

Creating the Image Gallery Component

Let's start by creating the main component for our scrollable gallery. We'll define an array of image URLs that will be displayed in the gallery.

Here's the initial structure of our ScrollGallery component:


"use client";
import { motion, useScroll, useTransform } from "framer-motion";
import React, { useRef } from "react";

const pictures = [
  // Add your image URLs here
];

const ScrollGallery = () => {
  return (
    <div>
      <TopSection />
      <ScrollGalleryComponent />
      <BottomSection />
    </div>
  );
};
          

Adding Image URLs

Replace the "// Add your image" URLs here comment with an array of image URLs. You can source images from platforms like Unsplash for high-quality visuals.

Implementing the Scroll Behavior

The core functionality of our gallery involves using the useScroll and useTransform hooks from Framer Motion to create a horizontal scrolling effect based on vertical scroll input.

ScrollGalleryComponent


const ScrollGalleryComponent = () => {
  const targetRef = useRef(null);
  const { scrollYProgress } = useScroll({
    target: targetRef,
    offset: ["start start", "end end"],
  });

  const x = useTransform(scrollYProgress, [0, 1], ["0%", "-350%"]);
  return (
    <section ref={targetRef} className="relative h-[300vh] bg-slate-900 border-y border-y-slate-700">
      <div className="sticky top-0 flex h-screen items-center overflow-hidden">
        <motion.div style={{ x }} className="flex gap-0.5">
          {pictures.map((pic, i) => (
            <img key={i} className="h-screen object-cover w-full aspect-square" src={pic} />
          ))}
        </motion.div>
      </div>
    </section>
  );
};
            

Explanation

  • useRef -> We create a reference for the section that will be scrolled.
  • useScroll -> This hook tracks the vertical scroll position.
  • useTransform -> This transforms the vertical scroll progress into a horizontal position for the images.

Adding Top and Bottom Sections

To enhance the user experience, we can add a top and bottom section to our gallery. These sections can serve as headers or footers.


const TopSection = () => {
  return (
    <div className="bg-slate-950 text-slate-500 italic h-[70vh] w-full flex items-center justify-center text-xs">
      Top Section
    </div>
  );
};

const BottomSection = () => {
  return (
    <div className="bg-slate-950 text-slate-500 italic h-[70vh] w-full flex items-center justify-center text-xs">
      Bottom Section
    </div>
  );
};
              

Conclusion

With these steps, you have created a responsive and visually engaging scrollable image gallery using React and Framer Motion. This gallery not only enhances the user experience but also showcases the power of animations in web applications. Feel free to customize the styles and images to fit your design preferences!

Github repository available!
Made With Kisses By Mohamed Rafik