Command Palette

Search for a command to run...

Horizontal Scroll

A vertically stacked set of collapsible containers allowing users to toggle content visibility. Customize the animation effects with variants and transitions for expanding/collapsing the sections.

Scroll to explore
Artwork 1

Artwork 1

Artwork 2

Artwork 2

Artwork 3

Artwork 3

Artwork 4

Artwork 4

Artwork 5

Artwork 5

End of scroll

Installation

Install the following dependencies:

pnpm add motion

Create a file at components/motions/horizontal-scroll.tsx and paste the given code.

"use client";
import { motion, useTransform, useScroll } from "motion/react";
import { useRef } from "react";
import { twMerge } from "tailwind-merge";
import CldImageComponent from "../cld-image";
 
interface HorizontalScrollProps {
    cards: {
        id: number;
        url: string;
        title: string;
    }[];
    className?: string;
}
 
interface CardProps {
    card: {
        id: number;
        url: string;
        title: string;
    };
}
 
export const HorizontalScroll = ({
    cards,
    className,
}: HorizontalScrollProps) => {
    const targetRef = useRef<HTMLDivElement>(null);
    const { scrollYProgress } = useScroll({
        target: targetRef,
    });
 
    const x = useTransform(scrollYProgress, [0, 1], ["1%", "-95%"]);
 
    return (
        <section
            ref={targetRef}
            className={twMerge("relative h-[300vh]", className)}
        >
            <div className="sticky top-0 flex h-screen items-center overflow-hidden">
                <motion.div style={{ x }} className="flex gap-4">
                    {cards.map((card) => (
                        <Card key={card.id} card={card} />
                    ))}
                </motion.div>
            </div>
        </section>
    );
};
 
const Card = ({ card }: CardProps) => {
    return (
        <div className="group relative h-[450px] w-[450px] overflow-hidden bg-neutral-200">
            <CldImageComponent
                src={card.url}
                alt={card.title}
                width={1920}
                height={1080}
                className="absolute inset-0 z-0 h-full w-full transition-transform duration-300 group-hover:scale-110 object-cover"
            />
 
            <div className="absolute inset-0 z-10 grid place-content-center">
                <p className="bg-gradient-to-br from-white/20 to-white/0 p-8 text-6xl font-black uppercase text-white backdrop-blur-lg">
                    {card.title}
                </p>
            </div>
        </div>
    );
};

Update the import paths to match your project setup.