feat: implement fixed header navigation bar scroll reveal with cinematic flight progress tracking

This commit is contained in:
Alaguraj0361 2026-07-15 16:18:20 +05:30
parent d35d28d026
commit b0a414a65e
9 changed files with 86 additions and 6 deletions

View File

@ -13,9 +13,11 @@ import Footer from "@/components/Footer";
import CustomCursor from "@/components/CustomCursor";
import SoundManager from "@/components/SoundManager";
import Header from "@/components/Header";
export default function Home() {
const [mounted, setMounted] = useState(false);
const [headerVisible, setHeaderVisible] = useState(false);
useEffect(() => {
setMounted(true);
@ -27,13 +29,17 @@ export default function Home() {
<div id="client-only-widgets">
{mounted && <SoundManager />}
{mounted && <CustomCursor />}
{mounted && <Header visible={headerVisible} />}
</div>
{/* Lenis Scroll syncing with GSAP triggers */}
<SmoothScroll>
{/* Sections 1 & 2: Landing Exterior Zoom & Door opening into Welcome reception */}
<EntranceExperience />
<EntranceExperience onProgress={(p) => {
console.log("[DEBUG onProgress]", p, "headerVisible:", p > 0.95);
setHeaderVisible(p > 0.95);
}} />
{/* Section 3: Heritage Story timeline */}
<RestaurantStory />

View File

@ -125,6 +125,7 @@ export default function ChefShowcase() {
return (
<section
ref={containerRef}
id="chef"
className="relative min-h-screen py-24 px-6 md:px-12 flex flex-col justify-center overflow-hidden z-20"
>
{/* Backdrop Chef Showcase Background Image */}

View File

@ -166,7 +166,7 @@ const ROW2_CATEGORIES = [
export default function CulinaryCategories() {
return (
<section className="relative w-full py-28 px-6 sm:px-12 md:px-16 lg:px-24 overflow-hidden z-20 bg-[#06120c]">
<section id="categories" className="relative w-full py-28 px-6 sm:px-12 md:px-16 lg:px-24 overflow-hidden z-20 bg-[#06120c]">
{/* Background Graphic Template Layer */}
<div className="absolute inset-0 z-0 pointer-events-none select-none">

View File

@ -277,7 +277,7 @@ function CinematicFlight({ progress }: { progress: number }) {
);
}
export default function EntranceExperience() {
export default function EntranceExperience({ onProgress }: { onProgress?: (progress: number) => void }) {
const containerRef = useRef<HTMLDivElement>(null);
const scrollIndicatorRef = useRef<HTMLDivElement>(null);
@ -306,6 +306,9 @@ export default function EntranceExperience() {
pin: true,
onUpdate: (self) => {
setScrollProgress(self.progress);
if (onProgress) {
onProgress(self.progress);
}
},
},
});

View File

@ -74,7 +74,7 @@ export default function EventsAccordion() {
];
return (
<section className="relative min-h-screen py-24 px-6 md:px-12 flex flex-col justify-center overflow-hidden bg-[#fdfcf7]">
<section id="events" className="relative min-h-screen py-24 px-6 md:px-12 flex flex-col justify-center overflow-hidden bg-[#fdfcf7]">
{/* Background Decorative Layer 1: Pillars setting in soft focus */}
<div className="absolute inset-0 bg-[url('/images/chettinad_interior.png')] bg-cover bg-center opacity-[0.06] pointer-events-none select-none z-0" />

View File

@ -16,7 +16,7 @@ export default function Footer() {
};
return (
<footer className="relative w-full py-16 px-6 sm:px-12 md:px-16 lg:px-24 overflow-hidden z-20">
<footer id="footer" className="relative w-full py-16 px-6 sm:px-12 md:px-16 lg:px-24 overflow-hidden z-20">
{/* Consolidated Mockup Background Layer */}
<div className="absolute inset-0 z-0 pointer-events-none select-none">

69
src/components/Header.tsx Normal file
View File

@ -0,0 +1,69 @@
"use client";
export default function Header({ visible }: { visible: boolean }) {
return (
<header
className={`fixed top-0 left-0 w-full h-16 bg-[#06120c]/85 border-b border-[#bc9e65]/20 backdrop-blur-md z-40 transition-transform duration-500 ease-in-out ${
visible ? "translate-y-0" : "-translate-y-full"
}`}
>
<div className="max-w-7xl mx-auto h-full px-6 flex items-center justify-between">
{/* Left Side: Brand Logo */}
<a href="#" className="clickable flex items-center gap-2.5 select-none">
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 21c4.5-3.5 6-7.5 6-10.5C18 7.5 15.5 6 12 10 8.5 6 6 7.5 6 10.5c0 3 1.5 7 6 10.5z" />
</svg>
<span className="font-serif text-[#bc9e65] text-xs sm:text-sm tracking-[0.25em] uppercase font-semibold">
MY DOSA PLACE
</span>
</a>
{/* Center: Navigation Links */}
<nav className="hidden md:flex items-center gap-8">
<a
href="#story"
className="clickable font-sans text-[10px] sm:text-xs tracking-widest uppercase text-stone-300 hover:text-[#bc9e65] transition-colors duration-300 font-bold"
>
Our Story
</a>
<a
href="#categories"
className="clickable font-sans text-[10px] sm:text-xs tracking-widest uppercase text-stone-300 hover:text-[#bc9e65] transition-colors duration-300 font-bold"
>
Categories
</a>
<a
href="#menu"
className="clickable font-sans text-[10px] sm:text-xs tracking-widest uppercase text-stone-300 hover:text-[#bc9e65] transition-colors duration-300 font-bold"
>
Feast Menu
</a>
<a
href="#chef"
className="clickable font-sans text-[10px] sm:text-xs tracking-widest uppercase text-stone-300 hover:text-[#bc9e65] transition-colors duration-300 font-bold"
>
Our Chef
</a>
<a
href="#events"
className="clickable font-sans text-[10px] sm:text-xs tracking-widest uppercase text-stone-300 hover:text-[#bc9e65] transition-colors duration-300 font-bold"
>
Banquets
</a>
</nav>
{/* Right Side: Reservation Button */}
<div className="flex items-center">
<a
href="#footer"
className="clickable px-4 sm:px-5 py-2 border border-[#bc9e65]/50 hover:border-[#bc9e65] rounded-full text-[9px] tracking-widest font-sans font-bold text-[#bc9e65] hover:bg-[#bc9e65] hover:text-[#06120c] transition-all duration-300 shadow-md"
>
RESERVE TABLE
</a>
</div>
</div>
</header>
);
}

View File

@ -232,6 +232,7 @@ export default function MenuPreview() {
return (
<section
ref={sectionRef}
id="menu"
className="relative min-h-screen py-24 md:py-32 px-6 sm:px-12 md:px-24 overflow-hidden select-none"
>
{/* Traditional Background Image containing pre-composed sketches, leaves, and brass pots */}

View File

@ -22,7 +22,7 @@ const StoryLotusDivider = () => (
export default function RestaurantStory() {
return (
<section className="relative py-24 md:py-32 px-6 sm:px-12 md:px-24 overflow-hidden select-none">
<section id="story" className="relative py-24 md:py-32 px-6 sm:px-12 md:px-24 overflow-hidden select-none">
{/* Traditional Background Image containing pre-composed sketches and mandalas */}
<Image
src="/images/story_bg.png"