80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
import { motion, useReducedMotion } from "framer-motion";
|
|
import Logo from "../../../assets/logo.svg";
|
|
|
|
interface OrbitConfig {
|
|
rotateZ: number;
|
|
rotateX: number;
|
|
duration: number;
|
|
reverse: boolean;
|
|
inset: string;
|
|
}
|
|
|
|
const orbits: OrbitConfig[] = [
|
|
{ rotateZ: 55, rotateX: 66, duration: 9, reverse: false, inset: "6%" },
|
|
{ rotateZ: -55, rotateX: 66, duration: 7, reverse: true, inset: "16%" },
|
|
];
|
|
|
|
const HeroVisual = () => {
|
|
const prefersReducedMotion = useReducedMotion();
|
|
|
|
return (
|
|
<div className="relative w-full max-w-xs sm:max-w-sm lg:max-w-lg mx-auto aspect-square">
|
|
<div className="absolute inset-[26%] rounded-full bg-gradient-to-br from-gold-light to-gold-dark opacity-30 blur-3xl" />
|
|
|
|
{orbits.map((orbit, i) => (
|
|
<motion.div
|
|
key={i}
|
|
className="absolute rounded-full border border-gold-light/30"
|
|
style={{
|
|
inset: orbit.inset,
|
|
transform: `rotateZ(${orbit.rotateZ}deg) rotateX(${orbit.rotateX}deg)`,
|
|
}}
|
|
initial={{ opacity: 0, scale: 0.85 }}
|
|
animate={{ opacity: 1, scale: 1 }}
|
|
transition={{
|
|
type: "spring",
|
|
damping: 20,
|
|
stiffness: 100,
|
|
delay: i * 0.15,
|
|
}}
|
|
>
|
|
<motion.div
|
|
className="absolute inset-0"
|
|
animate={{
|
|
rotate: prefersReducedMotion
|
|
? orbit.reverse
|
|
? -30
|
|
: 30
|
|
: orbit.reverse
|
|
? -360
|
|
: 360,
|
|
}}
|
|
transition={
|
|
prefersReducedMotion
|
|
? { duration: 0.6, ease: "easeOut" }
|
|
: {
|
|
duration: orbit.duration,
|
|
repeat: Infinity,
|
|
ease: "linear",
|
|
}
|
|
}
|
|
>
|
|
<span className="absolute -top-[5px] left-1/2 -translate-x-1/2 h-2.5 w-2.5 rounded-full bg-gold-light shadow-[0_0_10px_2px_rgba(250,204,151,0.55)]" />
|
|
</motion.div>
|
|
</motion.div>
|
|
))}
|
|
|
|
<motion.div
|
|
className="absolute inset-[32%] rounded-full glass-panel shadow-glass-lg flex items-center justify-center z-10"
|
|
initial={{ opacity: 0, scale: 0.8 }}
|
|
animate={{ opacity: 1, scale: 1 }}
|
|
transition={{ type: "spring", damping: 20, stiffness: 100 }}
|
|
>
|
|
<img src={Logo} alt="LK Results" className="w-2/5 h-2/5 opacity-90" />
|
|
</motion.div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default HeroVisual;
|