b
This commit is contained in:
76
components/ProjectSlider.tsx
Normal file
76
components/ProjectSlider.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
'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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user