added loading animation

This commit is contained in:
NicholaiVogel 2025-10-13 01:40:37 -06:00
parent 1589c35026
commit 3bafa982ee

View File

@ -26,6 +26,30 @@ function extractYouTubeVideoId(url: string): string | null {
return null; return null;
} }
// Animation variants for page load
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
delayChildren: 0.1,
},
},
};
const itemVariants = {
hidden: {
opacity: 0,
y: 20
},
visible: {
opacity: 1,
y: 0,
},
};
export function TempPlaceholder() { export function TempPlaceholder() {
const titleRef = useRef<HTMLHeadingElement | null>(null); const titleRef = useRef<HTMLHeadingElement | null>(null);
const titleInnerRef = useRef<HTMLSpanElement | null>(null); const titleInnerRef = useRef<HTMLSpanElement | null>(null);
@ -92,20 +116,54 @@ export function TempPlaceholder() {
opacity={0.5} opacity={0.5}
className="rounded" className="rounded"
/> />
<div className="relative z-10"> <motion.div
<p className="text-sm text-gray-500 mb-6">Last updated: 10-12-2025</p> className="relative z-10"
variants={containerVariants}
initial="hidden"
animate="visible"
transition={{
staggerChildren: 0.1,
delayChildren: 0.1,
}}
>
<motion.p
className="text-sm text-gray-500 mb-6"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
Last updated: 10-12-2025
</motion.p>
<h1 ref={titleRef} className="text-3xl sm:text-4xl md:text-5xl font-bold mb-4 leading-tight"> <motion.h1
ref={titleRef}
className="text-3xl sm:text-4xl md:text-5xl font-bold mb-4 leading-tight"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<span ref={titleInnerRef} className="inline-block"> <span ref={titleInnerRef} className="inline-block">
You've gotta be <em className="text-gray-400">shittin'</em> me. You've gotta be <em className="text-gray-400">shittin'</em> me.
</span> </span>
</h1> </motion.h1>
<p className="text-base sm:text-lg mb-2 text-gray-300">This is the 20th time this has happened.</p> <motion.p
<p className="text-base sm:text-lg mb-6 md:mb-8 text-gray-400"> className="text-base sm:text-lg mb-2 text-gray-300"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
This is the 20th time this has happened.
</motion.p>
<motion.p
className="text-base sm:text-lg mb-6 md:mb-8 text-gray-400"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<em>Nicholai broke the website, again.</em> <em>Nicholai broke the website, again.</em>
</p> </motion.p>
<div className="mb-8"> <motion.div
className="mb-8"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<HorizontalAccordion trigger="How did we get here?"> <HorizontalAccordion trigger="How did we get here?">
<div className="w-full"> <div className="w-full">
<p className="mb-4 text-gray-400 text-sm"> <p className="mb-4 text-gray-400 text-sm">
@ -133,8 +191,8 @@ export function TempPlaceholder() {
</ol> </ol>
</div> </div>
</HorizontalAccordion> </HorizontalAccordion>
</div> </motion.div>
<h1 <motion.h1
onClick={(e) => { onClick={(e) => {
setMousePosition({ x: e.clientX, y: e.clientY }); setMousePosition({ x: e.clientX, y: e.clientY });
setIsEasterEggOpen(true); setIsEasterEggOpen(true);
@ -145,11 +203,13 @@ export function TempPlaceholder() {
textShadow: '2px 2px 0px #ff4d00, 4px 4px 0px #ff4d00', textShadow: '2px 2px 0px #ff4d00, 4px 4px 0px #ff4d00',
width: titleWidth ? `${titleWidth}px` : undefined width: titleWidth ? `${titleWidth}px` : undefined
}} }}
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
> >
<span ref={bioTextRef} className="inline-block" style={{ fontSize: bioFontSizePx ? `${bioFontSizePx}px` : undefined }}> <span ref={bioTextRef} className="inline-block" style={{ fontSize: bioFontSizePx ? `${bioFontSizePx}px` : undefined }}>
BIOHAZARD BIOHAZARD
</span> </span>
</h1> </motion.h1>
<AnimatePresence> <AnimatePresence>
{isEasterEggOpen && ( {isEasterEggOpen && (
@ -254,12 +314,20 @@ export function TempPlaceholder() {
</> </>
)} )}
</AnimatePresence> </AnimatePresence>
<p className="mb-6 md:mb-8 text-base sm:text-lg text-gray-300"> <motion.p
className="mb-6 md:mb-8 text-base sm:text-lg text-gray-300"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<strong>Who we are:</strong> artists and technical people, we're <strong>Who we are:</strong> artists and technical people, we're
better at VFX than we are at web design, I promise. better at VFX than we are at web design, I promise.
</p> </motion.p>
<p className="mb-4 text-base sm:text-lg"> <motion.p
className="mb-4 text-base sm:text-lg"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<strong>Here's our reel:</strong>{" "} <strong>Here's our reel:</strong>{" "}
<a <a
href="https://f.io/Wgx3EAHu" href="https://f.io/Wgx3EAHu"
@ -270,14 +338,26 @@ export function TempPlaceholder() {
> >
Biohazard Reel Mar 2025 - Frame.io Biohazard Reel Mar 2025 - Frame.io
</a> </a>
</p> </motion.p>
<p className="mb-4 md:mb-6 text-base sm:text-lg"> <motion.p
className="mb-4 md:mb-6 text-base sm:text-lg"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<strong>Some projects we've worked on:</strong> <strong>Some projects we've worked on:</strong>
</p> </motion.p>
<ul className="mb-6 md:mb-8 space-y-3 md:space-y-4 text-sm sm:text-base"> <motion.ul
<li className="flex items-start"> className="mb-6 md:mb-8 space-y-3 md:space-y-4 text-sm sm:text-base"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<motion.li
className="flex items-start"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<span className="text-gray-400 mr-3 mt-1"></span> <span className="text-gray-400 mr-3 mt-1"></span>
<a <a
href="https://www.instagram.com/biohazardvfx/" href="https://www.instagram.com/biohazardvfx/"
@ -288,8 +368,12 @@ export function TempPlaceholder() {
> >
Gstar Raw - Pommelhorse Gstar Raw - Pommelhorse
</a> </a>
</li> </motion.li>
<li className="flex items-start"> <motion.li
className="flex items-start"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<span className="text-gray-400 mr-3 mt-1"></span> <span className="text-gray-400 mr-3 mt-1"></span>
<HoverCard> <HoverCard>
<HoverCardTrigger asChild> <HoverCardTrigger asChild>
@ -305,7 +389,7 @@ export function TempPlaceholder() {
<span className="hidden sm:inline"> (feat. Morgan Wallen)</span> <span className="hidden sm:inline"> (feat. Morgan Wallen)</span>
</a> </a>
</HoverCardTrigger> </HoverCardTrigger>
<HoverCardContent className="w-80 p-0 bg-black border-gray-800"> <HoverCardContent className="w-80 p-0 bg-black border-gray-800 z-50">
<iframe <iframe
width="320" width="320"
height="180" height="180"
@ -318,8 +402,12 @@ export function TempPlaceholder() {
/> />
</HoverCardContent> </HoverCardContent>
</HoverCard> </HoverCard>
</li> </motion.li>
<li className="flex items-start"> <motion.li
className="flex items-start"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<span className="text-gray-400 mr-3 mt-1"></span> <span className="text-gray-400 mr-3 mt-1"></span>
<HoverCard> <HoverCard>
<HoverCardTrigger asChild> <HoverCardTrigger asChild>
@ -333,7 +421,7 @@ export function TempPlaceholder() {
The Wait Is Over | OFFICIAL TRAILER The Wait Is Over | OFFICIAL TRAILER
</a> </a>
</HoverCardTrigger> </HoverCardTrigger>
<HoverCardContent className="w-80 p-0 bg-black border-gray-800"> <HoverCardContent className="w-80 p-0 bg-black border-gray-800 z-50">
<iframe <iframe
width="320" width="320"
height="180" height="180"
@ -346,8 +434,12 @@ export function TempPlaceholder() {
/> />
</HoverCardContent> </HoverCardContent>
</HoverCard> </HoverCard>
</li> </motion.li>
<li className="flex items-start"> <motion.li
className="flex items-start"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<span className="text-gray-400 mr-3 mt-1"></span> <span className="text-gray-400 mr-3 mt-1"></span>
<HoverCard> <HoverCard>
<HoverCardTrigger asChild> <HoverCardTrigger asChild>
@ -361,7 +453,7 @@ export function TempPlaceholder() {
2hollis Star Album Trailer 2hollis Star Album Trailer
</a> </a>
</HoverCardTrigger> </HoverCardTrigger>
<HoverCardContent className="w-80 p-0 bg-black border-gray-800"> <HoverCardContent className="w-80 p-0 bg-black border-gray-800 z-50">
<iframe <iframe
width="320" width="320"
height="180" height="180"
@ -374,8 +466,12 @@ export function TempPlaceholder() {
/> />
</HoverCardContent> </HoverCardContent>
</HoverCard> </HoverCard>
</li> </motion.li>
<li className="flex items-start"> <motion.li
className="flex items-start"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<span className="text-gray-400 mr-3 mt-1"></span> <span className="text-gray-400 mr-3 mt-1"></span>
<HoverCard> <HoverCard>
<HoverCardTrigger asChild> <HoverCardTrigger asChild>
@ -389,7 +485,7 @@ export function TempPlaceholder() {
Thanksgiving With Kai, Kevin &amp; Druski Thanksgiving With Kai, Kevin &amp; Druski
</a> </a>
</HoverCardTrigger> </HoverCardTrigger>
<HoverCardContent className="w-80 p-0 bg-black border-gray-800"> <HoverCardContent className="w-80 p-0 bg-black border-gray-800 z-50">
<iframe <iframe
width="320" width="320"
height="180" height="180"
@ -402,8 +498,12 @@ export function TempPlaceholder() {
/> />
</HoverCardContent> </HoverCardContent>
</HoverCard> </HoverCard>
</li> </motion.li>
<li className="flex items-start"> <motion.li
className="flex items-start"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<span className="text-gray-400 mr-3 mt-1"></span> <span className="text-gray-400 mr-3 mt-1"></span>
<HoverCard> <HoverCard>
<HoverCardTrigger asChild> <HoverCardTrigger asChild>
@ -419,7 +519,7 @@ export function TempPlaceholder() {
<span className="hidden sm:inline"> (With or Without You) Official MV</span> <span className="hidden sm:inline"> (With or Without You) Official MV</span>
</a> </a>
</HoverCardTrigger> </HoverCardTrigger>
<HoverCardContent className="w-80 p-0 bg-black border-gray-800"> <HoverCardContent className="w-80 p-0 bg-black border-gray-800 z-50">
<iframe <iframe
width="320" width="320"
height="180" height="180"
@ -432,12 +532,21 @@ export function TempPlaceholder() {
/> />
</HoverCardContent> </HoverCardContent>
</HoverCard> </HoverCard>
</li> </motion.li>
</ul> </motion.ul>
<motion.div
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
<InstagramFeed /> <InstagramFeed />
</motion.div>
<p className="mb-2 text-sm sm:text-base text-gray-300"> <motion.p
className="mb-2 text-sm sm:text-base text-gray-300"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
Contact us:{" "} Contact us:{" "}
<a <a
href="mailto:contact@biohazardvfx.com" href="mailto:contact@biohazardvfx.com"
@ -448,8 +557,12 @@ export function TempPlaceholder() {
> >
contact@biohazardvfx.com contact@biohazardvfx.com
</a> </a>
</p> </motion.p>
<p className="text-sm sm:text-base text-gray-300"> <motion.p
className="text-sm sm:text-base text-gray-300"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
>
File a complaint:{" "} File a complaint:{" "}
<a <a
href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" href="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
@ -460,18 +573,20 @@ export function TempPlaceholder() {
> >
help@biohazardvfx.com help@biohazardvfx.com
</a> </a>
</p> </motion.p>
<p <motion.p
onClick={(e) => { onClick={(e) => {
setPigeonMousePosition({ x: e.clientX, y: e.clientY }); setPigeonMousePosition({ x: e.clientX, y: e.clientY });
setIsPigeonEggOpen(true); setIsPigeonEggOpen(true);
}} }}
className="text-xs text-gray-600 mt-4 cursor-pointer hover:text-gray-500 transition-colors" className="text-xs text-gray-600 mt-4 cursor-pointer hover:text-gray-500 transition-colors"
variants={itemVariants}
transition={{ duration: 0.4, ease: "easeOut" }}
> >
No pigeons allowed in this zone No pigeons allowed in this zone
</p> </motion.p>
</div> </motion.div>
</div> </div>
</div> </div>
</section> </section>