77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import { useRef, useEffect } from 'react'
|
|
import { motion, useAnimationFrame } from 'framer-motion'
|
|
import Image from 'next/image'
|
|
import { Project } from '@/data/projects'
|
|
|
|
interface ProjectSliderProps {
|
|
projects: Project[]
|
|
}
|
|
|
|
export default function ProjectSlider({ projects }: ProjectSliderProps) {
|
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
|
|
// Duplicate projects for seamless infinite loop
|
|
const doubledProjects = [...projects, ...projects]
|
|
|
|
// Speed of the automatic scroll
|
|
const speed = 0.8
|
|
|
|
useAnimationFrame(() => {
|
|
if (!containerRef.current) return
|
|
|
|
containerRef.current.scrollLeft += speed
|
|
|
|
const firstHalfWidth = containerRef.current.scrollWidth / 2
|
|
|
|
if (containerRef.current.scrollLeft >= firstHalfWidth) {
|
|
containerRef.current.scrollLeft = 0
|
|
}
|
|
})
|
|
|
|
const handleWheel = (e: React.WheelEvent) => {
|
|
if (!containerRef.current) return
|
|
containerRef.current.scrollLeft += e.deltaY
|
|
}
|
|
|
|
return (
|
|
<div
|
|
ref={containerRef}
|
|
onWheel={handleWheel}
|
|
className="flex-1 flex items-center overflow-x-auto no-scrollbar cursor-grab active:cursor-grabbing py-10"
|
|
>
|
|
<div className="flex space-x-6 md:space-x-12 px-6 md:px-10">
|
|
{doubledProjects.map((project, idx) => (
|
|
<div
|
|
key={`${project.id}-${idx}`}
|
|
className="group relative flex-shrink-0 w-[80vw] sm:w-[500px] md:w-[600px]"
|
|
>
|
|
{/* Image Container */}
|
|
<div className="relative aspect-[4/3] overflow-hidden rounded-[1px]">
|
|
<Image
|
|
src={project.image}
|
|
alt={project.title}
|
|
fill
|
|
sizes="(max-width: 768px) 80vw, 600px"
|
|
className="object-cover grayscale hover:grayscale-0 transition-all duration-700 ease-in-out scale-110 group-hover:scale-100"
|
|
/>
|
|
</div>
|
|
|
|
{/* Project Info */}
|
|
<div className="mt-4 flex justify-between items-start opacity-0 group-hover:opacity-100 transition-opacity duration-500">
|
|
<div className="text-[10px] md:text-[12px] font-bold text-black tracking-wider uppercase">
|
|
{project.year} — {project.location}
|
|
</div>
|
|
<div className="flex items-center space-x-2 text-[10px] md:text-[12px] font-bold text-black tracking-wider uppercase">
|
|
<span>{project.title}</span>
|
|
<span className="text-sm md:text-lg">→</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|