diff --git a/web/src/app/(root)/BentoGrid.tsx b/web/src/app/(root)/BentoGrid.tsx index c48217b..df8cc5f 100644 --- a/web/src/app/(root)/BentoGrid.tsx +++ b/web/src/app/(root)/BentoGrid.tsx @@ -49,7 +49,7 @@ export default function BentoGrid() {
- + Available for work diff --git a/web/src/app/(root)/Footer.tsx b/web/src/app/(root)/Footer.tsx index 052532b..1a7ded4 100644 --- a/web/src/app/(root)/Footer.tsx +++ b/web/src/app/(root)/Footer.tsx @@ -35,12 +35,6 @@ export default function Footer() { > Blogs - - Admin -
diff --git a/web/src/app/(root)/SectionWrapper.tsx b/web/src/app/(root)/SectionWrapper.tsx new file mode 100644 index 0000000..64120f5 --- /dev/null +++ b/web/src/app/(root)/SectionWrapper.tsx @@ -0,0 +1,91 @@ +'use client'; +import { ReactNode, useEffect, useRef } from 'react'; +import Footer from './Footer'; +import BentoGrid from './BentoGrid'; +import HeroSection from './HeroSection'; +import { gsap, ScrollSmoother } from '@/lib/gsap'; + +export default function SectionWrapper({ + children, + loading, +}: { + children: ReactNode; + loading: boolean; +}) { + const mainLayerRef = useRef(null); + const secondLayerRef = useRef(null); + const thirdLayerRef = useRef(null); + const pinWrapRef = useRef(null); + + useEffect(() => { + if (loading) return; + + const smoother = ScrollSmoother.create({ smooth: 3, effects: true }); + + const ctx = gsap.context(() => { + gsap.set(mainLayerRef.current, { clipPath: 'inset(0% 0% 0% 0%)' }); + gsap.set(secondLayerRef.current, { clipPath: 'inset(0% 0% 0% 0%)' }); + gsap.set(thirdLayerRef.current, { clipPath: 'inset(0% 0% 0% 0%)' }); + + const tl = gsap.timeline({ + scrollTrigger: { + trigger: pinWrapRef.current, + start: 'top top', + end: '+=300%', + scrub: true, + pin: true, + }, + }); + + tl.to(mainLayerRef.current, { + clipPath: 'inset(0% 0% 100% 0%)', + ease: 'none', + }); + + tl.to(secondLayerRef.current, { + clipPath: 'inset(0% 0% 100% 0%)', + ease: 'none', + }); + + tl.to(thirdLayerRef.current, { + clipPath: 'inset(0% 0% 100% 0%)', + ease: 'none', + }); + }); + + return () => { + ctx.revert(); + smoother.kill(); + }; + }, [loading]); + return ( + <> +
+
+
+
+ +
+ +
+ +
+ +
+
+ {children} +
+
+
+ + ); +} diff --git a/web/src/app/(root)/components/ScrollIndicator.tsx b/web/src/app/(root)/components/ScrollIndicator.tsx index 5f0c52c..4946a1f 100644 --- a/web/src/app/(root)/components/ScrollIndicator.tsx +++ b/web/src/app/(root)/components/ScrollIndicator.tsx @@ -1,37 +1,10 @@ 'use client'; -import { useEffect, useRef } from 'react'; import { ChevronDown } from 'lucide-react'; -export function ScrollIndicator({ - progressRef, -}: { - progressRef?: React.MutableRefObject; -}) { - const ref = useRef(null); - - useEffect(() => { - if (!progressRef) return; - - let raf: number; - const tick = () => { - if (ref.current) { - const opacity = Math.max(0, 1 - progressRef.current / 0.15); - ref.current.style.opacity = String(opacity); - ref.current.style.pointerEvents = opacity <= 0 ? 'none' : 'auto'; - } - raf = requestAnimationFrame(tick); - }; - tick(); - - return () => cancelAnimationFrame(raf); - }, [progressRef]); - +export function ScrollIndicator() { return ( -
+
Scroll diff --git a/web/src/app/(root)/page.tsx b/web/src/app/(root)/page.tsx index 92b4fe5..8e26faa 100644 --- a/web/src/app/(root)/page.tsx +++ b/web/src/app/(root)/page.tsx @@ -1,8 +1,8 @@ 'use client'; -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; -import { gsap, ScrollSmoother } from '@/lib/gsap'; +import { ScrollSmoother } from '@/lib/gsap'; import { DisplacementSphere } from '@/components/model/displacement-sphere'; @@ -17,10 +17,8 @@ import { useSession } from 'next-auth/react'; import Logo from '@/components/Logo'; import { TextIntro } from '@/components/Animations'; import { TransitionLink } from '@/components/Navigation'; -import HeroSection from './HeroSection'; +import SectionWrapper from './SectionWrapper'; import { ScrollIndicator } from './components/ScrollIndicator'; -import BentoGrid from './BentoGrid'; -import Footer from './Footer'; // import { seedData } from '@/data/seed'; let introAlreadyPlayed = false; @@ -83,254 +81,172 @@ export default function Home() { }); }, [loading]); - const mainLayerRef = useRef(null); - const secondLayerRef = useRef(null); - const thirdLayerRef = useRef(null); - const pinWrapRef = useRef(null); - const scrollProgressRef = useRef(0); - - useEffect(() => { - if (loading) return; - - const smoother = ScrollSmoother.create({ smooth: 3, effects: true }); - - const ctx = gsap.context(() => { - gsap.set(mainLayerRef.current, { clipPath: 'inset(0% 0% 0% 0%)' }); - gsap.set(secondLayerRef.current, { clipPath: 'inset(0% 0% 0% 0%)' }); - gsap.set(thirdLayerRef.current, { clipPath: 'inset(0% 0% 0% 0%)' }); - - const tl = gsap.timeline({ - scrollTrigger: { - trigger: pinWrapRef.current, - start: 'top top', - end: '+=300%', - scrub: true, - pin: true, - onUpdate: (self) => { - scrollProgressRef.current = self.progress; - }, - }, - }); - - tl.to(mainLayerRef.current, { - clipPath: 'inset(0% 0% 100% 0%)', - ease: 'none', - }); - - tl.to(secondLayerRef.current, { - clipPath: 'inset(0% 0% 100% 0%)', - ease: 'none', - }); - - tl.to(thirdLayerRef.current, { - clipPath: 'inset(0% 0% 100% 0%)', - ease: 'none', - }); - }); - - return () => { - ctx.revert(); - smoother.kill(); - }; - }, [loading]); return ( <>
-
-
-
-
- -
- -
- -
- -
-
-
-
- { - setSphereReady(true); - }} - /> -
+ +
+
+ { + setSphereReady(true); + }} + /> +
+ + {!loading && ( +
+
+
setHomePageHover('logo')} + onMouseLeave={() => setHomePageHover(null)} + className={`${getClass('logo')} ${ + homePageHover === 'logo' ? 'scale-110' : 'scale-100' + }`} + > + +
- {!loading && ( -
-
+
setHomePageHover('logo')} + onMouseEnter={() => setHomePageHover('blogs')} onMouseLeave={() => setHomePageHover(null)} - className={`${getClass('logo')} ${ - homePageHover === 'logo' ? 'scale-110' : 'scale-100' + className={`${getClass('blogs')} ${ + homePageHover === 'blogs' ? 'scale-110' : 'scale-100' }`} > - -
- -
-
setHomePageHover('blogs')} - onMouseLeave={() => setHomePageHover(null)} - className={`${getClass('blogs')} ${ - homePageHover === 'blogs' - ? 'scale-110' - : 'scale-100' - }`} - > - - - Blogs - - -
- -
setHomePageHover('theme')} - onMouseLeave={() => setHomePageHover(null)} - className={`${getClass('theme')} ${ - homePageHover === 'theme' - ? 'scale-110' - : 'scale-100' - }`} - > - - - -
- -
{ - setHomePageHover('signin'); - setThreeDModelBlur(true); - }} - onMouseLeave={() => { - setHomePageHover(null); - setThreeDModelBlur(false); - }} - className={`${getClass('signin')} ${ - homePageHover === 'signin' - ? 'scale-110' - : 'scale-100' - }`} - > - - - -
-
-
- {session && ( -
setHomePageHover('signin')} - onMouseLeave={() => setHomePageHover(null)} - className={`${getClass('signin')} ${ - homePageHover === 'signin' - ? 'scale-110' - : 'scale-100' - }`} + + -

- Logged in as {session.user.name} -

-
- )} -
setHomePageHover('admin')} - onMouseLeave={() => setHomePageHover(null)} - className={`${getClass('admin')} ${ - homePageHover === 'admin' - ? 'scale-110' - : 'scale-100' - }`} - > - {session?.user.role === 'admin' && ( - - - Admin - - - )} -
+ Blogs + +
-
-

setHomePageHover('tech')} + onMouseEnter={() => setHomePageHover('theme')} onMouseLeave={() => setHomePageHover(null)} - className={`${getClass('tech')} ${ - homePageHover === 'tech' ? 'scale-110' : 'scale-100' + className={`${getClass('theme')} ${ + homePageHover === 'theme' ? 'scale-110' : 'scale-100' }`} > - -
- tech blogs 2026 -
-
+ + +
setHomePageHover('coding')} - onMouseLeave={() => setHomePageHover(null)} - className={`${getClass('coding')} ${ - homePageHover === 'coding' ? 'scale-110' : 'scale-100' + onMouseEnter={() => { + setHomePageHover('signin'); + setThreeDModelBlur(true); + }} + onMouseLeave={() => { + setHomePageHover(null); + setThreeDModelBlur(false); + }} + className={`${getClass('signin')} ${ + homePageHover === 'signin' ? 'scale-110' : 'scale-100' }`} > - -
- Coding -
-
+ + +
- +

+
+ {session && ( +
setHomePageHover('signin')} + onMouseLeave={() => setHomePageHover(null)} + className={`${getClass('signin')} ${ + homePageHover === 'signin' + ? 'scale-110' + : 'scale-100' + }`} + > +

+ Logged in as {session.user.name} +

+
+ )}
setHomePageHover('logs')} + onMouseEnter={() => setHomePageHover('admin')} onMouseLeave={() => setHomePageHover(null)} - className={`${getClass('logs')} ${ - homePageHover === 'logs' ? 'scale-110' : 'scale-100' + className={`${getClass('admin')} ${ + homePageHover === 'admin' ? 'scale-110' : 'scale-100' }`} > - -
- Logs -
-
+ {session?.user.role === 'admin' && ( + + + Admin + + + )}
- +
- )} - -
-
-
-
+

+
setHomePageHover('tech')} + onMouseLeave={() => setHomePageHover(null)} + className={`${getClass('tech')} ${ + homePageHover === 'tech' ? 'scale-110' : 'scale-100' + }`} + > + +
+ tech blogs 2026 +
+
+
+ +
setHomePageHover('coding')} + onMouseLeave={() => setHomePageHover(null)} + className={`${getClass('coding')} ${ + homePageHover === 'coding' ? 'scale-110' : 'scale-100' + }`} + > + +
+ Coding +
+
+
+ +
setHomePageHover('logs')} + onMouseLeave={() => setHomePageHover(null)} + className={`${getClass('logs')} ${ + homePageHover === 'logs' ? 'scale-110' : 'scale-100' + }`} + > + +
+ Logs +
+
+
+

+
+ )} + + +