"use client"; import { useMemo } from "react"; import { useMediaQuery } from "@/hooks/useMediaQuery"; /** * GalaxyBackground Component * * Creates a cosmic background effect that fades up from the bottom of the page. * Features: * - Subtle gradient fading from bottom (prominent) to top (transparent) * - Floating star-like particles * - More prominent at the bottom, fading as it goes higher * - Customizable colors from Vibrant.js for artist/album pages */ interface GalaxyBackgroundProps { /** Primary color extracted from Vibrant.js (e.g., "#8B4789") */ primaryColor?: string; /** Optional secondary color */ secondaryColor?: string; } export function GalaxyBackground({ primaryColor, secondaryColor }: GalaxyBackgroundProps = {}) { // Performance optimization: disable animations on mobile and for reduced-motion preference const isMobile = useMediaQuery("(max-width: 768px)"); const prefersReducedMotion = useMediaQuery("(prefers-reduced-motion: reduce)"); const shouldDisableAnimations = isMobile || prefersReducedMotion; // Convert hex color to RGB values for opacity control const hexToRgb = (hex: string) => { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; }; // Use provided colors or default purple theme const baseColor = primaryColor ? hexToRgb(primaryColor) : null; const accentColor = secondaryColor ? hexToRgb(secondaryColor) : null; // Memoize particle positions so they don't regenerate on every render const particles = useMemo(() => ({ bottom: Array(30).fill(0).map(() => ({ left: Math.random() * 100, bottom: Math.random() * 30, duration: 3 + Math.random() * 4, delay: Math.random() * 3, })), mid: Array(20).fill(0).map(() => ({ left: Math.random() * 100, bottom: 30 + Math.random() * 30, duration: 4 + Math.random() * 3, delay: Math.random() * 2, })), top: Array(12).fill(0).map(() => ({ left: Math.random() * 100, bottom: 60 + Math.random() * 40, duration: 5 + Math.random() * 3, delay: Math.random() * 2, })), white: Array(18).fill(0).map(() => ({ left: Math.random() * 100, bottom: Math.random() * 50, duration: 2 + Math.random() * 3, delay: Math.random() * 2, })), accent: Array(10).fill(0).map(() => ({ left: Math.random() * 100, bottom: Math.random() * 40, duration: 4 + Math.random() * 4, delay: Math.random() * 3, })), }), []); // Empty dependency array - generate once and never again return (