b
This commit is contained in:
87
app/projects/page.tsx
Normal file
87
app/projects/page.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
'use client'
|
||||
|
||||
import { motion, useScroll, useTransform } from 'framer-motion'
|
||||
import Image from 'next/image'
|
||||
import { projects } from '@/data/projects'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export default function ProjectsPage() {
|
||||
const { scrollY } = useScroll()
|
||||
const [isAtBottom, setIsAtBottom] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const windowHeight = window.innerHeight
|
||||
const documentHeight = document.documentElement.scrollHeight
|
||||
const scrollPosition = window.scrollY + windowHeight
|
||||
setIsAtBottom(scrollPosition > documentHeight - 100)
|
||||
}
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => window.removeEventListener('scroll', handleScroll)
|
||||
}, [])
|
||||
|
||||
const cargoFontSize = useTransform(scrollY, [0, 300], ["10vw", "4vw"])
|
||||
const archFontSize = useTransform(scrollY, [0, 300], ["8vw", "3vw"])
|
||||
const bottomPadding = useTransform(scrollY, [0, 300], ["2.5rem", "1rem"])
|
||||
|
||||
return (
|
||||
<main className="relative min-h-screen bg-white pt-32 pb-60 px-6 md:px-10">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 md:gap-8">
|
||||
{projects.map((project, idx) => (
|
||||
<motion.div
|
||||
key={project.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: idx * 0.05 }}
|
||||
className="group cursor-pointer"
|
||||
>
|
||||
<div className="relative aspect-[4/3] overflow-hidden rounded-[1px] bg-zinc-100">
|
||||
<Image
|
||||
src={project.image}
|
||||
alt={project.title}
|
||||
fill
|
||||
className="object-cover grayscale group-hover:grayscale-0 transition-all duration-700 ease-in-out scale-105 group-hover:scale-100"
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-4 flex flex-col space-y-1 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
||||
<span className="text-[10px] font-bold text-black/60 uppercase tracking-wider">
|
||||
{project.year} — {project.location}
|
||||
</span>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-[10px] font-bold text-black uppercase tracking-widest">
|
||||
{project.title}
|
||||
</span>
|
||||
<span className="text-sm">→</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
animate={{ opacity: isAtBottom ? 0 : 1 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="fixed bottom-0 left-0 w-full pointer-events-none z-50 overflow-hidden pt-10"
|
||||
>
|
||||
<motion.div
|
||||
style={{ padding: bottomPadding }}
|
||||
className="flex justify-between items-end"
|
||||
>
|
||||
<motion.h1
|
||||
style={{ fontSize: cargoFontSize }}
|
||||
className="font-bebas leading-[0.8] text-black tracking-tighter"
|
||||
>
|
||||
A.N.T
|
||||
</motion.h1>
|
||||
<motion.h1
|
||||
style={{ fontSize: archFontSize }}
|
||||
className="font-bebas leading-[0.8] text-black tracking-tighter"
|
||||
>
|
||||
ARCHITECTURE
|
||||
</motion.h1>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
</main>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user