Add logo loading screen gated on animation readiness
- Full-screen loader whose only content is the logo animating: the "B" draws in and fills, the base facets trace in, then a wave runs along them until the page is ready (pure CSS, plays before JS) - Loader gate holds the loader until GSAP + fonts and every 3D scene's first frame are ready, then waits 1s (min 1.4s total) before leaving; hard 8s limit, head-script fallback if JS never boots - Scroll reveals, SplitText and scene entry animations start only once the loader leaves, so above-the-fold entries play in view - Internal links fade the loader back in before navigating, so page changes are one seamless dark transition - No loader for no-JS or reduced-motion visitors Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1,15 +1,30 @@
|
||||
import React from "react";
|
||||
import { holdLoader } from "../loader/gate";
|
||||
|
||||
/** Boot the site-wide GSAP motion system (see ./motion.ts). */
|
||||
/**
|
||||
* Boot the site-wide GSAP motion system (see ./motion.ts). Holds the page
|
||||
* loader until GSAP is loaded and fonts are settled, so SplitText measures
|
||||
* final line breaks.
|
||||
*/
|
||||
export default function useMotion() {
|
||||
React.useEffect(() => {
|
||||
let destroy: (() => void) | undefined;
|
||||
let cancelled = false;
|
||||
import("./motion").then(({ initMotion }) => {
|
||||
if (!cancelled) destroy = initMotion();
|
||||
});
|
||||
const release = holdLoader("motion");
|
||||
|
||||
Promise.all([
|
||||
import("./motion"),
|
||||
document.fonts?.ready.catch(() => {}),
|
||||
])
|
||||
.then(([{ initMotion }]) => {
|
||||
if (!cancelled) destroy = initMotion();
|
||||
})
|
||||
.catch((error) => console.warn("Motion failed to load", error))
|
||||
.finally(release);
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
release();
|
||||
destroy?.();
|
||||
};
|
||||
}, []);
|
||||
|
||||
Reference in New Issue
Block a user