feat: implement fixed header navigation bar scroll reveal with cinematic flight progress tracking
This commit is contained in:
parent
d35d28d026
commit
b0a414a65e
@ -13,9 +13,11 @@ import Footer from "@/components/Footer";
|
|||||||
|
|
||||||
import CustomCursor from "@/components/CustomCursor";
|
import CustomCursor from "@/components/CustomCursor";
|
||||||
import SoundManager from "@/components/SoundManager";
|
import SoundManager from "@/components/SoundManager";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [mounted, setMounted] = useState(false);
|
const [mounted, setMounted] = useState(false);
|
||||||
|
const [headerVisible, setHeaderVisible] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMounted(true);
|
setMounted(true);
|
||||||
@ -27,13 +29,17 @@ export default function Home() {
|
|||||||
<div id="client-only-widgets">
|
<div id="client-only-widgets">
|
||||||
{mounted && <SoundManager />}
|
{mounted && <SoundManager />}
|
||||||
{mounted && <CustomCursor />}
|
{mounted && <CustomCursor />}
|
||||||
|
{mounted && <Header visible={headerVisible} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Lenis Scroll syncing with GSAP triggers */}
|
{/* Lenis Scroll syncing with GSAP triggers */}
|
||||||
<SmoothScroll>
|
<SmoothScroll>
|
||||||
|
|
||||||
{/* Sections 1 & 2: Landing Exterior Zoom & Door opening into Welcome reception */}
|
{/* 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 */}
|
{/* Section 3: Heritage Story timeline */}
|
||||||
<RestaurantStory />
|
<RestaurantStory />
|
||||||
|
|||||||
@ -125,6 +125,7 @@ export default function ChefShowcase() {
|
|||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
ref={containerRef}
|
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"
|
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 */}
|
{/* Backdrop Chef Showcase Background Image */}
|
||||||
|
|||||||
@ -166,7 +166,7 @@ const ROW2_CATEGORIES = [
|
|||||||
|
|
||||||
export default function CulinaryCategories() {
|
export default function CulinaryCategories() {
|
||||||
return (
|
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 */}
|
{/* Background Graphic Template Layer */}
|
||||||
<div className="absolute inset-0 z-0 pointer-events-none select-none">
|
<div className="absolute inset-0 z-0 pointer-events-none select-none">
|
||||||
|
|||||||
@ -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 containerRef = useRef<HTMLDivElement>(null);
|
||||||
const scrollIndicatorRef = useRef<HTMLDivElement>(null);
|
const scrollIndicatorRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@ -306,6 +306,9 @@ export default function EntranceExperience() {
|
|||||||
pin: true,
|
pin: true,
|
||||||
onUpdate: (self) => {
|
onUpdate: (self) => {
|
||||||
setScrollProgress(self.progress);
|
setScrollProgress(self.progress);
|
||||||
|
if (onProgress) {
|
||||||
|
onProgress(self.progress);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -74,7 +74,7 @@ export default function EventsAccordion() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
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 */}
|
{/* 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" />
|
<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" />
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export default function Footer() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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 */}
|
{/* Consolidated Mockup Background Layer */}
|
||||||
<div className="absolute inset-0 z-0 pointer-events-none select-none">
|
<div className="absolute inset-0 z-0 pointer-events-none select-none">
|
||||||
|
|||||||
69
src/components/Header.tsx
Normal file
69
src/components/Header.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -232,6 +232,7 @@ export default function MenuPreview() {
|
|||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
ref={sectionRef}
|
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"
|
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 */}
|
{/* Traditional Background Image containing pre-composed sketches, leaves, and brass pots */}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ const StoryLotusDivider = () => (
|
|||||||
|
|
||||||
export default function RestaurantStory() {
|
export default function RestaurantStory() {
|
||||||
return (
|
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 */}
|
{/* Traditional Background Image containing pre-composed sketches and mandalas */}
|
||||||
<Image
|
<Image
|
||||||
src="/images/story_bg.png"
|
src="/images/story_bg.png"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user