added loading animation
This commit is contained in:
parent
1589c35026
commit
3bafa982ee
@ -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 & Druski
|
Thanksgiving With Kai, Kevin & 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>
|
||||||
|
|
||||||
<InstagramFeed />
|
<motion.div
|
||||||
|
variants={itemVariants}
|
||||||
|
transition={{ duration: 0.4, ease: "easeOut" }}
|
||||||
|
>
|
||||||
|
<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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user