Image Pile
ImagePile shuffles and layers images dynamically, creating a stylish, ever-changing visual effect. Built with React, Next.js, Framer Motion, and Tailwind CSS, itβs perfect for portfolios, galleries, and landing pages. Add motion and personality to your UI effortlessly! ππ¨
Preview
Follow below steps ππ»
Install dependencies
npm i framer-motion
Component
Create a file image-pile.tsx in your components folder and paste this code
'use client';
import React, { useEffect, useState } from 'react';
import Image from 'next/image';
import { motion } from 'framer-motion';
const ImagePile = ({ images, speed = 2 }: { images: string[]; speed?: number }) => {
const [topIndex, setTopIndex] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setTopIndex((prevIndex) => (prevIndex + 1) % images.length);
}, speed * 1000);
return () => {
clearInterval(id);
};
}, [images.length]);
return (
<div className="relative h-[200px] sm:h-[260px] md:h-[390px] lg:h-[450px] xl:h-[500px] w-[310px] sm:w-[500px] md:w-[725px] lg:w-[900px] xl:w-[1200px] overflow-visible">
{images.map((image, i) => {
const key = `stacked-card-${i}`;
const isTop = topIndex === i;
const secondTopIndex = (topIndex + 2) % images.length;
const zIndex = isTop ? 100 : secondTopIndex ? 99 : images.length - i;
const y: number = Math.random() * 20;
const x: number = Math.random() * 20;
const rotation = i * (Math.random() * 1 + 2) - 2;
return (
<motion.div
key={key}
className="absolute w-full h-full"
style={{
zIndex,
transformOrigin: 'center center'
}}
animate={{
rotateZ: isTop ? 0 : rotation,
translateX: Math.random() < 0.5 ? x : -x,
opacity: isTop ? [0, 1] : 0.8,
translateY: isTop ? [30, Math.random() < 0.5 ? y : -y] : Math.random() < 0.5 ? y : -y,
transition: {
duration: 0.5
}
}}
initial={isTop ? { rotateZ: 0 } : { rotateZ: rotation }}
>
<div className="relative h-full w-full overflow-hidden rounded-3xl">
<Image
src={image}
alt={`stacked-card-${i}`}
height={1080}
width={1920}
className="h-full w-full object-cover"
priority={isTop}
/>
</div>
</motion.div>
);
})}
</div>
);
};
export default ImagePile;
Usage
<ImagePile
images={[
'https://images.unsplash.com/photo-1731770241468-8337b047749f?q=80&w=3870&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1728993559783-f657d4177c6b?q=80&w=3870&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1638392436949-3e584046314a?q=80&w=3870&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1726880066148-fdc1ceba7343?q=80&w=3876&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
]}
/>