update about page

This commit is contained in:
2026-06-02 14:10:44 +05:30
parent a59a5e79dc
commit bae2fa0daa
24 changed files with 1903 additions and 1052 deletions

View File

@@ -1,6 +1,7 @@
"use client";
import React, { useEffect } from "react";
import { usePathname } from "next/navigation";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
@@ -10,6 +11,51 @@ import { ScrollTrigger } from "gsap/ScrollTrigger";
* and provides smooth defaults.
*/
export default function AnimationProvider({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
const initDecorativeBlocks = () => {
// Clean up previous block triggers to avoid duplicates
ScrollTrigger.getAll().forEach((t) => {
if (t.vars && (t.vars as any).id === "block-deco") {
t.kill();
}
});
const vh = window.innerHeight || document.documentElement.clientHeight;
const decorativeBlocks = document.querySelectorAll(".block-decoration");
decorativeBlocks.forEach((block) => {
ScrollTrigger.create({
id: "block-deco",
trigger: block,
start: "top 92%",
onEnter: () => {
setTimeout(() => {
block.classList.add("animated");
}, 150);
},
onEnterBack: () => {
setTimeout(() => {
block.classList.add("animated");
}, 150);
},
onLeave: () => {
block.classList.remove("animated");
},
onLeaveBack: () => {
block.classList.remove("animated");
},
});
// ScrollTrigger does not fire onEnter for blocks already in view at
// creation — on larger / taller screens those stayed un-animated.
// Reveal any block already intersecting the viewport.
const r = block.getBoundingClientRect();
if (r.top < vh && r.bottom > 0) {
block.classList.add("animated");
}
});
};
useEffect(() => {
gsap.registerPlugin(ScrollTrigger);
@@ -24,72 +70,9 @@ export default function AnimationProvider({ children }: { children: React.ReactN
// re-hidden animations on phones. Ignore those spurious resizes.
ScrollTrigger.config({ ignoreMobileResize: true });
const initDecorativeBlocks = () => {
// Clean up previous block triggers to avoid duplicates
ScrollTrigger.getAll().forEach((t) => {
if (t.vars && (t.vars as any).id === "block-deco") {
t.kill();
}
});
const vh = window.innerHeight || document.documentElement.clientHeight;
const decorativeBlocks = document.querySelectorAll(".block-decoration");
decorativeBlocks.forEach((block) => {
ScrollTrigger.create({
id: "block-deco",
trigger: block,
start: "top 92%",
onEnter: () => {
setTimeout(() => {
block.classList.add("animated");
}, 150);
},
onEnterBack: () => {
setTimeout(() => {
block.classList.add("animated");
}, 150);
},
onLeave: () => {
block.classList.remove("animated");
},
onLeaveBack: () => {
block.classList.remove("animated");
},
});
// ScrollTrigger does not fire onEnter for blocks already in view at
// creation — on larger / taller screens those stayed un-animated.
// Reveal any block already intersecting the viewport.
const r = block.getBoundingClientRect();
if (r.top < vh && r.bottom > 0) {
block.classList.add("animated");
}
});
};
// Run initializations
initDecorativeBlocks();
// Refresh ScrollTrigger at staggered intervals to account for lazy-loaded assets/images over the network
const timeouts = [
setTimeout(() => {
initDecorativeBlocks();
ScrollTrigger.refresh(true);
}, 100),
setTimeout(() => {
initDecorativeBlocks();
ScrollTrigger.refresh(true);
}, 500),
setTimeout(() => {
initDecorativeBlocks();
ScrollTrigger.refresh(true);
}, 1500),
setTimeout(() => {
initDecorativeBlocks();
ScrollTrigger.refresh(true);
}, 3000),
];
// Refresh on full window load (when all images, styles, and fonts are in place)
const handleLoad = () => {
initDecorativeBlocks();
@@ -111,7 +94,6 @@ export default function AnimationProvider({ children }: { children: React.ReactN
window.addEventListener("resize", handleResize);
return () => {
timeouts.forEach(clearTimeout);
clearTimeout(resizeTimer);
window.removeEventListener("load", handleLoad);
window.removeEventListener("resize", handleResize);
@@ -119,6 +101,29 @@ export default function AnimationProvider({ children }: { children: React.ReactN
};
}, []);
// Listen for route changes and refresh ScrollTriggers so newly rendered content animates in correctly
useEffect(() => {
const refreshAnimations = () => {
initDecorativeBlocks();
ScrollTrigger.refresh(true);
};
// Run route change handler immediately on navigation
refreshAnimations();
// Staggered refreshes to accommodate page layout calculations and paint frames
const timers = [
setTimeout(refreshAnimations, 100),
setTimeout(refreshAnimations, 400),
setTimeout(refreshAnimations, 800),
setTimeout(refreshAnimations, 1500),
];
return () => {
timers.forEach(clearTimeout);
};
}, [pathname]);
return <>{children}</>;
}