84 lines
3.2 KiB
TypeScript
84 lines
3.2 KiB
TypeScript
"use client";
|
|
|
|
import Image from "next/image";
|
|
import { useEffect, useRef, useState } from "react";
|
|
|
|
const stages = [
|
|
{ tab: "Roots In UP", title: "Roots in Uttar Pradesh", sub: "Homes, festivals and the culture we carry within.", img: "/img/home_10_.jpg" },
|
|
{ tab: "Cities", title: "New Cities, New Beginnings", sub: "Arriving in North Texas with hope and ambition.", img: "/img/home_9_.jpg" },
|
|
{ tab: "The Journey", title: "The Journey Together", sub: "A WhatsApp message becomes a parivaar.", img: "/img/home_14_.jpg" },
|
|
{ tab: "Dallas", title: "Rooted in Dallas", sub: "Thousands of families, dozens of events.", img: "/img/home_6_.jpg" },
|
|
{ tab: "UP Parivar", title: "One UP Parivar", sub: "A trusted network fostering belonging.", img: "/img/home_5_.jpg" },
|
|
{ tab: "Future", title: "A Borderless Future", sub: "Connection and cultural pride, worldwide.", img: "/img/home_2_.jpg" },
|
|
];
|
|
|
|
export default function JourneyBanner() {
|
|
const [active, setActive] = useState(0);
|
|
const sectionRef = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
let frame = 0;
|
|
const onScroll = () => {
|
|
if (frame) return;
|
|
frame = requestAnimationFrame(() => {
|
|
frame = 0;
|
|
const el = sectionRef.current;
|
|
if (!el) return;
|
|
const rect = el.getBoundingClientRect();
|
|
const total = rect.height - window.innerHeight;
|
|
const scrolled = Math.min(Math.max(-rect.top, 0), total);
|
|
const progress = total > 0 ? scrolled / total : 0;
|
|
const idx = Math.min(stages.length - 1, Math.floor(progress * stages.length));
|
|
setActive(idx);
|
|
});
|
|
};
|
|
onScroll();
|
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
window.addEventListener("resize", onScroll);
|
|
return () => {
|
|
window.removeEventListener("scroll", onScroll);
|
|
window.removeEventListener("resize", onScroll);
|
|
if (frame) cancelAnimationFrame(frame);
|
|
};
|
|
}, []);
|
|
|
|
const current = stages[active];
|
|
|
|
return (
|
|
<section ref={sectionRef} className="jbanner">
|
|
<div className="jbanner__stage">
|
|
{stages.map((s, i) => (
|
|
<div
|
|
key={s.tab}
|
|
className={`jbanner__slide ${i === active ? "jbanner__slide--active" : ""}`}
|
|
aria-hidden={i !== active}
|
|
>
|
|
<Image src={s.img} alt={s.title} fill priority={i === 0} className="img-cover" sizes="100vw" />
|
|
</div>
|
|
))}
|
|
<div className="jbanner__overlay" />
|
|
|
|
<div className="container jbanner__inner">
|
|
<div className="jbanner__content" key={active}>
|
|
<span className="eyebrow-light">◉ Our Journey</span>
|
|
<h2 className="jbanner__title">{current.title}</h2>
|
|
<p className="jbanner__sub">{current.sub}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="jbanner__tabs">
|
|
{stages.map((s, i) => (
|
|
<div
|
|
key={s.tab}
|
|
className={`jbanner__tab ${i === active ? "jbanner__tab--active" : ""}`}
|
|
>
|
|
<p className="jbanner__tab-title">{s.tab}</p>
|
|
<p className="jbanner__tab-sub">Melas, garba nights.</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|