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:
Julien Froidefond
2025-12-09 14:32:45 +01:00
parent b8f4672206
commit 6dc08dc818

View File

@@ -2,94 +2,9 @@
import { useBackgroundImage } from "@/hooks/usePreferences";
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() {
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 (
<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 */}
<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>
{/* Hero Content */}
@@ -233,120 +66,6 @@ export default function HeroSection() {
</Link>
</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>
);
}