Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 60 additions & 14 deletions app/Gallery/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,36 @@ const images = [
"/Assets/Images/cj8.jpg",
];

const IMAGE_WIDTH = 600 + 48; // width + 2*mx-6 (24px each side)
// Responsive image width and margin
const getImageWidth = () => {
if (typeof window === "undefined") return 600 + 48;
if (window.innerWidth < 640) return 320 + 24; // mobile: 320px + 2*mx-3
if (window.innerWidth < 1024) return 480 + 32; // tablet: 480px + 2*mx-4
return 600 + 48; // desktop: 600px + 2*mx-6
};

const Gallery = () => {
const controls = useAnimation();
const [isPaused, setIsPaused] = useState(false);
<<<<<<< HEAD
const [offset, setOffset] = useState(0);
const [imageWidth, setImageWidth] = useState(getImageWidth());

// Update image width on resize
useEffect(() => {
const handleResize = () => setImageWidth(getImageWidth());
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
=======
const [offset, setOffset] = useState(0); // offset in px
>>>>>>> f44a310707bb1d1606c8f6f0471ed10d89ff7476

// Start animation
useEffect(() => {
if (!isPaused) {
controls.start({
x: [offset, offset - (images.length * IMAGE_WIDTH)],
x: [offset, offset - (images.length * imageWidth)],
transition: {
repeat: Infinity,
repeatType: "loop",
Expand All @@ -43,41 +61,55 @@ const Gallery = () => {
controls.stop();
}
// eslint-disable-next-line
}, [isPaused, offset, controls]);
}, [isPaused, offset, controls, imageWidth]);

// When hover, set offset so hovered image is first
// When hover/tap, set offset so hovered image is first
const handleMouseEnter = (idx: number) => {
setIsPaused(true);
<<<<<<< HEAD
setOffset(-idx * imageWidth);
controls.set({ x: -idx * imageWidth });
=======
setOffset(-idx * IMAGE_WIDTH);
controls.set({ x: -idx * IMAGE_WIDTH });
>>>>>>> f44a310707bb1d1606c8f6f0471ed10d89ff7476
};

// On leave, resume animation from current offset
const handleMouseLeave = () => {
setIsPaused(false);
<<<<<<< HEAD
};

// For mobile: handle tap to pause and focus image
const handleTouch = (idx: number) => {
handleMouseEnter(idx);
setTimeout(() => setIsPaused(false), 2000); // Resume after 2s
=======
>>>>>>> f44a310707bb1d1606c8f6f0471ed10d89ff7476
};

return (
<div className="w-full min-h-screen bg-black">
<NavBar />

<div className="container mx-auto pt-32 pb-20 px-4 md:px-8 lg:px-16">
<div className="container mx-auto pt-32 pb-20 px-2 sm:px-4 md:px-8 lg:px-16">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
className="text-center mb-12"
>
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-4">
<h1 className="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-4">
Our <span className="text-primary">Gallery</span>
</h1>
<p className="text-white/70 max-w-2xl mx-auto text-lg">
<p className="text-white/70 max-w-2xl mx-auto text-base sm:text-lg">
Explore our collection of memorable moments and achievements
</p>
</motion.div>

<div className="flex justify-center">
<div className="overflow-hidden w-full max-w-6xl mx-auto rounded-xl border border-white/10 shadow-lg">
<div className="overflow-hidden w-full max-w-full sm:max-w-2xl md:max-w-4xl lg:max-w-6xl mx-auto rounded-xl border border-white/10 shadow-lg">
<motion.div
className="flex"
style={{ width: "max-content" }}
Expand All @@ -86,10 +118,23 @@ const Gallery = () => {
{[...images, ...images].map((src, idx) => (
<motion.div
key={idx}
className="relative flex-shrink-0 mx-6"
className={`
relative flex-shrink-0
mx-3 sm:mx-4 lg:mx-6
`}
style={{
width: "600px",
height: "340px",
width:
imageWidth === 320 + 24
? 320
: imageWidth === 480 + 32
? 480
: 600,
height:
imageWidth === 320 + 24
? 180
: imageWidth === 480 + 32
? 270
: 340,
}}
whileHover={{
scale: 1.08,
Expand All @@ -98,17 +143,18 @@ const Gallery = () => {
}}
onMouseEnter={() => handleMouseEnter(idx % images.length)}
onMouseLeave={handleMouseLeave}
onTouchStart={() => handleTouch(idx % images.length)}
>
<Image
src={src}
alt={`Gallery Image ${idx + 1}`}
fill
className="object-cover rounded-xl"
sizes="(max-width: 768px) 90vw, (max-width: 1200px) 45vw, 600px"
sizes="(max-width: 640px) 90vw, (max-width: 1024px) 45vw, 600px"
priority={idx === 0}
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-0 hover:opacity-100 transition-opacity duration-300 flex items-end justify-center p-6 rounded-xl">
<p className="text-white text-base md:text-xl font-medium text-center">
<div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-0 hover:opacity-100 transition-opacity duration-300 flex items-end justify-center p-3 sm:p-6 rounded-xl">
<p className="text-white text-xs sm:text-base md:text-xl font-medium text-center">
Capturing our journey of innovation and collaboration
</p>
</div>
Expand Down