Refactor HeroSection component: Remove particle and orb animations to simplify the code and improve performance. Streamline the component structure while maintaining the existing background image functionality.
This commit is contained in:
@@ -2,94 +2,9 @@
|
|||||||
|
|
||||||
import { useBackgroundImage } from "@/hooks/usePreferences";
|
import { useBackgroundImage } from "@/hooks/usePreferences";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useState, useEffect } from "react";
|
|
||||||
|
|
||||||
interface Particle {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
left: number;
|
|
||||||
top: number;
|
|
||||||
duration: number;
|
|
||||||
delay: number;
|
|
||||||
shadow: number;
|
|
||||||
fadeIn: number;
|
|
||||||
fadeOut: number;
|
|
||||||
visibleDuration: number;
|
|
||||||
moveY1: number;
|
|
||||||
moveX1: number;
|
|
||||||
moveY2: number;
|
|
||||||
moveX2: number;
|
|
||||||
moveY3: number;
|
|
||||||
moveX3: number;
|
|
||||||
moveY4: number;
|
|
||||||
moveX4: number;
|
|
||||||
moveY5: number;
|
|
||||||
moveX5: number;
|
|
||||||
moveY6: number;
|
|
||||||
moveX6: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Orb {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
left: number;
|
|
||||||
top: number;
|
|
||||||
duration: number;
|
|
||||||
delay: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function HeroSection() {
|
export default function HeroSection() {
|
||||||
const backgroundImage = useBackgroundImage("home", "/got-2.jpg");
|
const backgroundImage = useBackgroundImage("home", "/got-2.jpg");
|
||||||
const [particles, setParticles] = useState<Particle[]>([]);
|
|
||||||
const [orbs, setOrbs] = useState<Orb[]>([]);
|
|
||||||
const [mounted, setMounted] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setMounted(true);
|
|
||||||
// Generate particles - more visible and dynamic
|
|
||||||
setParticles(
|
|
||||||
Array.from({ length: 30 }, () => {
|
|
||||||
const fadeIn = Math.random() * 5 + 2; // 2-7% of animation - faster fade in
|
|
||||||
const visibleDuration = Math.random() * 30 + 20; // 20-50% of animation
|
|
||||||
const fadeOut = Math.random() * 5 + 2; // 2-7% of animation - faster fade out
|
|
||||||
return {
|
|
||||||
width: Math.random() * 6 + 3,
|
|
||||||
height: Math.random() * 6 + 3,
|
|
||||||
left: Math.random() * 100,
|
|
||||||
top: Math.random() * 100,
|
|
||||||
duration: 10 + Math.random() * 15,
|
|
||||||
delay: Math.random() * 8,
|
|
||||||
shadow: Math.random() * 15 + 8,
|
|
||||||
fadeIn: fadeIn,
|
|
||||||
fadeOut: fadeOut,
|
|
||||||
visibleDuration: visibleDuration,
|
|
||||||
moveY1: 20 + Math.random() * 20,
|
|
||||||
moveX1: Math.random() * 10 - 5,
|
|
||||||
moveY2: 40 + Math.random() * 20,
|
|
||||||
moveX2: Math.random() * 15 - 7,
|
|
||||||
moveY3: 60 + Math.random() * 20,
|
|
||||||
moveX3: Math.random() * 10 - 5,
|
|
||||||
moveY4: 80 + Math.random() * 20,
|
|
||||||
moveX4: Math.random() * 10 - 5,
|
|
||||||
moveY5: 100 + Math.random() * 20,
|
|
||||||
moveX5: Math.random() * 10 - 5,
|
|
||||||
moveY6: 120 + Math.random() * 20,
|
|
||||||
moveX6: Math.random() * 10 - 5,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// Generate orbs
|
|
||||||
setOrbs(
|
|
||||||
Array.from({ length: 4 }, () => ({
|
|
||||||
width: 100 + Math.random() * 200,
|
|
||||||
height: 100 + Math.random() * 200,
|
|
||||||
left: Math.random() * 80,
|
|
||||||
top: Math.random() * 80,
|
|
||||||
duration: 20 + Math.random() * 15,
|
|
||||||
delay: Math.random() * 10,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="relative w-full min-h-screen flex flex-col items-center justify-center overflow-hidden pt-24">
|
<section className="relative w-full min-h-screen flex flex-col items-center justify-center overflow-hidden pt-24">
|
||||||
@@ -102,88 +17,6 @@ export default function HeroSection() {
|
|||||||
>
|
>
|
||||||
{/* Dark overlay for readability */}
|
{/* Dark overlay for readability */}
|
||||||
<div className="absolute inset-0 bg-gradient-to-b from-black/70 via-black/60 to-black/80 z-[1]"></div>
|
<div className="absolute inset-0 bg-gradient-to-b from-black/70 via-black/60 to-black/80 z-[1]"></div>
|
||||||
|
|
||||||
{/* Animated particles */}
|
|
||||||
{mounted && (
|
|
||||||
<div className="absolute inset-0 overflow-hidden z-[2]">
|
|
||||||
{particles.map((particle, i) => (
|
|
||||||
<div
|
|
||||||
key={i}
|
|
||||||
className="absolute rounded-full"
|
|
||||||
style={{
|
|
||||||
width: `${particle.width}px`,
|
|
||||||
height: `${particle.height}px`,
|
|
||||||
left: `${particle.left}%`,
|
|
||||||
top: `${particle.top}%`,
|
|
||||||
background: `radial-gradient(circle, rgba(218, 165, 32, 0.9) 0%, rgba(218, 165, 32, 0.4) 50%, transparent 100%)`,
|
|
||||||
animation: `float-particle-${i} ${particle.duration}s infinite ease-in-out`,
|
|
||||||
animationDelay: `${particle.delay}s`,
|
|
||||||
boxShadow: `0 0 ${
|
|
||||||
particle.shadow
|
|
||||||
}px rgba(218, 165, 32, 0.8), 0 0 ${
|
|
||||||
particle.shadow * 2
|
|
||||||
}px rgba(218, 165, 32, 0.4)`,
|
|
||||||
filter: "blur(0.5px)",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Animated light rays */}
|
|
||||||
<div className="absolute inset-0 overflow-hidden opacity-30">
|
|
||||||
{[...Array(3)].map((_, i) => {
|
|
||||||
const rotation = -15 + i * 15;
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={i}
|
|
||||||
className="absolute w-1 bg-gradient-to-b from-transparent via-pixel-gold/20 to-transparent"
|
|
||||||
style={{
|
|
||||||
height: "100%",
|
|
||||||
left: `${20 + i * 30}%`,
|
|
||||||
transform: `rotate(${rotation}deg)`,
|
|
||||||
animation: `light-ray-${i} ${
|
|
||||||
8 + i * 2
|
|
||||||
}s infinite ease-in-out`,
|
|
||||||
animationDelay: `${i * 2}s`,
|
|
||||||
transformOrigin: "top center",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Glowing orbs */}
|
|
||||||
{mounted && (
|
|
||||||
<div className="absolute inset-0 overflow-hidden">
|
|
||||||
{orbs.map((orb, i) => (
|
|
||||||
<div
|
|
||||||
key={i}
|
|
||||||
className="absolute rounded-full blur-xl"
|
|
||||||
style={{
|
|
||||||
width: `${orb.width}px`,
|
|
||||||
height: `${orb.height}px`,
|
|
||||||
left: `${orb.left}%`,
|
|
||||||
top: `${orb.top}%`,
|
|
||||||
background: `radial-gradient(circle, rgba(218, 165, 32, 0.2) 0%, transparent 70%)`,
|
|
||||||
animation: `orb-float ${orb.duration}s infinite ease-in-out`,
|
|
||||||
animationDelay: `${orb.delay}s`,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Shimmer effect */}
|
|
||||||
<div className="absolute inset-0 overflow-hidden">
|
|
||||||
<div
|
|
||||||
className="absolute inset-0 bg-gradient-to-r from-transparent via-pixel-gold/10 to-transparent"
|
|
||||||
style={{
|
|
||||||
transform: "skewX(-20deg)",
|
|
||||||
animation: "shimmer 8s infinite",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Hero Content */}
|
{/* Hero Content */}
|
||||||
@@ -233,120 +66,6 @@ export default function HeroSection() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style jsx>{`
|
|
||||||
@keyframes float {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
transform: translateY(0px);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translateY(-20px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
${particles
|
|
||||||
.map((particle, i) => {
|
|
||||||
const fadeInPercent = particle.fadeIn;
|
|
||||||
const visibleStart = fadeInPercent;
|
|
||||||
const visibleEnd = visibleStart + particle.visibleDuration;
|
|
||||||
const fadeOutStart = visibleEnd;
|
|
||||||
const fadeOutEnd = Math.min(100, fadeOutStart + particle.fadeOut);
|
|
||||||
|
|
||||||
return `
|
|
||||||
@keyframes float-particle-${i} {
|
|
||||||
0% {
|
|
||||||
transform: translateY(0px) translateX(0px) scale(0.8);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
${fadeInPercent}% {
|
|
||||||
transform: translateY(-${particle.moveY1}px) translateX(${particle.moveX1}px) scale(1);
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
${visibleStart}% {
|
|
||||||
transform: translateY(-${particle.moveY2}px) translateX(${particle.moveX2}px) scale(1.1);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
${visibleEnd}% {
|
|
||||||
transform: translateY(-${particle.moveY3}px) translateX(${particle.moveX3}px) scale(1.05);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
${fadeOutStart}% {
|
|
||||||
transform: translateY(-${particle.moveY4}px) translateX(${particle.moveX4}px) scale(0.9);
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
${fadeOutEnd}% {
|
|
||||||
transform: translateY(-${particle.moveY5}px) translateX(${particle.moveX5}px) scale(0.5);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateY(-${particle.moveY6}px) translateX(${particle.moveX6}px) scale(0.3);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
})
|
|
||||||
.join("")}
|
|
||||||
|
|
||||||
@keyframes light-ray-0 {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
opacity: 0.2;
|
|
||||||
transform: rotate(-15deg) scaleY(0.8);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 0.5;
|
|
||||||
transform: rotate(-15deg) scaleY(1.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes light-ray-1 {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
opacity: 0.2;
|
|
||||||
transform: rotate(0deg) scaleY(0.8);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 0.5;
|
|
||||||
transform: rotate(0deg) scaleY(1.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes light-ray-2 {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
opacity: 0.2;
|
|
||||||
transform: rotate(15deg) scaleY(0.8);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 0.5;
|
|
||||||
transform: rotate(15deg) scaleY(1.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes orb-float {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
transform: translate(0, 0) scale(1);
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
33% {
|
|
||||||
transform: translate(30px, -30px) scale(1.1);
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
66% {
|
|
||||||
transform: translate(-20px, 20px) scale(0.9);
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes shimmer {
|
|
||||||
0% {
|
|
||||||
transform: translateX(-100%) skewX(-20deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateX(200%) skewX(-20deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user