css-3d-carousel

ui

src

tailwind.css

CSS
@theme {
    @keyframes rotate-y {
        from {
            transform: perspective(1200px) rotateY(0deg);
        }
        to {
            transform: perspective(1200px) rotateY(360deg);
        }
    }
    --animate-rotate-y: rotate-y 15s linear infinite;
}

page.tsx

TSX
export default function Page() {

    const images = [
        "https://cdn.pixabay.com/photo/2023/05/08/08/41/ai-7977960_1280.jpg",
        "https://cdn.pixabay.com/photo/2020/05/25/17/03/merry-christmas-5219496_1280.jpg",
        "https://cdn.pixabay.com/photo/2020/07/08/04/12/work-5382501_1280.jpg",
        "https://cdn.pixabay.com/photo/2014/07/06/13/55/calculator-385506_1280.jpg",
        "https://cdn.pixabay.com/photo/2020/04/20/18/10/cinema-5069314_1280.jpg",
        "https://cdn.pixabay.com/photo/2016/03/11/02/08/speedometer-1249610_1280.jpg",
        "https://cdn.pixabay.com/photo/2016/11/21/16/27/laptop-1846277_1280.jpg",
        "https://cdn.pixabay.com/photo/2015/10/21/08/22/media-998990_1280.jpg",
        "https://cdn.pixabay.com/photo/2018/05/08/08/44/artificial-intelligence-3382507_1280.jpg",
    ];

    return (
        <div className="[--r:160px] md:[--r:320px] lg:[--r:420px]">
            <div className="flex justify-center items-center bg-black py-32">
                <section
                    className="relative w-20 md:w-32 lg:w-56 aspect-video transform-[perspective(1200px)] transform-3d animate-rotate-y">
                    {
                        images.map((url, i) => (
                            <img className="size-full object-center absolute inset-0 shadow-2xl shadow-slate-300/30"
                                 style={ {
                                     transform: `rotateY(${ 360 / images.length * i }deg) translateZ(var(--r))`,
                                 } }
                                 src={ url }
                                 alt=""
                                 key={ i }/>
                        ))
                    }
                </section>
            </div>
        </div>
    )
}

video