bayarea-cc/src/components/home/BackgroundAnimations.tsx

245 lines
7.1 KiB
TypeScript

import { motion } from 'framer-motion';
import { useMemo } from 'react';
const BackgroundAnimations = () => {
// Particles with better visibility (increased opacity and size)
const particles = useMemo(() => {
return Array.from({ length: 18 }, (_, i) => ({
id: i,
x: Math.random() * 100,
y: Math.random() * 100,
size: Math.random() * 4 + 2, // Larger particles (2-6px instead of 1-3px)
duration: Math.random() * 10 + 6,
delay: Math.random() * 4,
opacity: Math.random() * 0.4 + 0.5, // Much higher opacity (0.5-0.9)
}));
}, []);
// Circuit nodes for tech effect
const circuitNodes = useMemo(() => {
return Array.from({ length: 8 }, (_, i) => ({
id: i,
x: Math.random() * 80 + 10,
y: Math.random() * 80 + 10,
pulseDelay: Math.random() * 2,
}));
}, []);
// Connection lines between nodes
const connectionLines = useMemo(() => {
const lines = [];
for (let i = 0; i < circuitNodes.length - 1; i++) {
if (i + 1 < circuitNodes.length) {
lines.push({
id: i,
x1: circuitNodes[i].x,
y1: circuitNodes[i].y,
x2: circuitNodes[i + 1].x,
y2: circuitNodes[i + 1].y,
});
}
}
return lines;
}, [circuitNodes]);
return (
<div className="absolute inset-0 overflow-hidden pointer-events-none" style={{ willChange: 'transform' }}>
{/* Animated Grid Background */}
<motion.div
className="absolute inset-0"
style={{
backgroundImage: `
linear-gradient(to right, rgba(51, 102, 255, 0.08) 1px, transparent 1px),
linear-gradient(to bottom, rgba(51, 102, 255, 0.08) 1px, transparent 1px)
`,
backgroundSize: '60px 60px',
willChange: 'transform',
}}
animate={{
opacity: [0.3, 0.5, 0.3],
}}
transition={{
duration: 4,
repeat: Infinity,
ease: "easeInOut",
}}
/>
{/* SVG Container for Lines and Nodes */}
<svg className="absolute inset-0 w-full h-full" style={{ willChange: 'transform' }}>
{/* Animated Connection Lines */}
{connectionLines.map((line) => (
<motion.line
key={line.id}
x1={`${line.x1}%`}
y1={`${line.y1}%`}
x2={`${line.x2}%`}
y2={`${line.y2}%`}
stroke="rgba(51, 102, 255, 0.4)"
strokeWidth="1.5"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: [0.3, 0.7, 0.3] }}
transition={{
pathLength: { duration: 2, delay: line.id * 0.3 },
opacity: { duration: 3, repeat: Infinity, ease: "easeInOut" },
}}
/>
))}
{/* Vertical Data Streams */}
{[...Array(6)].map((_, i) => (
<motion.line
key={`vertical-${i}`}
x1={`${10 + i * 18}%`}
y1="0%"
x2={`${10 + i * 18}%`}
y2="100%"
stroke="rgba(51, 102, 255, 0.3)"
strokeWidth="1.5"
strokeDasharray="8 16"
initial={{ strokeDashoffset: 0 }}
animate={{ strokeDashoffset: 100 }}
transition={{
duration: 3,
repeat: Infinity,
ease: "linear",
delay: i * 0.4,
}}
/>
))}
{/* Circuit Nodes with pulse ring */}
{circuitNodes.map((node) => (
<g key={node.id}>
{/* Pulse ring */}
<motion.circle
cx={`${node.x}%`}
cy={`${node.y}%`}
r="6"
fill="none"
stroke="#3366ff"
strokeWidth="1"
animate={{
r: [6, 12, 6],
opacity: [0.8, 0, 0.8],
}}
transition={{
duration: 2.5,
repeat: Infinity,
delay: node.pulseDelay,
ease: "easeOut",
}}
/>
{/* Core node */}
<motion.circle
cx={`${node.x}%`}
cy={`${node.y}%`}
r="4"
fill="#3366ff"
animate={{
opacity: [0.7, 1, 0.7],
r: [3, 4.5, 3],
}}
transition={{
duration: 2,
repeat: Infinity,
delay: node.pulseDelay,
ease: "easeInOut",
}}
/>
</g>
))}
</svg>
{/* Floating Data Particles - highly visible */}
{particles.map((particle) => (
<motion.div
key={particle.id}
className="absolute rounded-full bg-neon"
style={{
width: `${particle.size}px`,
height: `${particle.size}px`,
left: `${particle.x}%`,
top: `${particle.y}%`,
boxShadow: '0 0 12px rgba(51, 102, 255, 0.9), 0 0 24px rgba(51, 102, 255, 0.5)',
willChange: 'transform, opacity',
}}
animate={{
y: [0, -500],
opacity: [0, particle.opacity, particle.opacity, 0],
}}
transition={{
duration: particle.duration,
repeat: Infinity,
delay: particle.delay,
ease: "linear",
}}
/>
))}
{/* Scanline Effect */}
<motion.div
className="absolute inset-0 pointer-events-none"
style={{
background: `repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(51, 102, 255, 0.04) 2px,
rgba(51, 102, 255, 0.04) 4px
)`,
}}
animate={{
opacity: [0.3, 0.5, 0.3],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut",
}}
/>
{/* Radial Glows */}
{[
{ x: 20, y: 30, size: 300 },
{ x: 80, y: 70, size: 350 },
{ x: 50, y: 50, size: 400 },
].map((pos, i) => (
<motion.div
key={`glow-${i}`}
className="absolute rounded-full pointer-events-none"
style={{
left: `${pos.x}%`,
top: `${pos.y}%`,
width: `${pos.size}px`,
height: `${pos.size}px`,
background: 'radial-gradient(circle, rgba(51, 102, 255, 0.25) 0%, transparent 70%)',
transform: 'translate(-50%, -50%)',
willChange: 'transform',
}}
animate={{
scale: [1, 1.3, 1],
opacity: [0.5, 0.8, 0.5],
}}
transition={{
duration: 5,
repeat: Infinity,
delay: i * 1.5,
ease: "easeInOut",
}}
/>
))}
{/* Corner Accent Glows */}
<div className="absolute top-0 left-0 w-96 h-96 bg-gradient-to-br from-neon/20 to-transparent rounded-full opacity-60 pointer-events-none" />
<div className="absolute bottom-0 right-0 w-[500px] h-[500px] bg-gradient-to-tl from-neon/20 to-transparent rounded-full opacity-60 pointer-events-none" />
</div>
);
};
export default BackgroundAnimations;