animations
This commit is contained in:
parent
1c5f272f33
commit
91b819e9c1
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(npm run build:*)",
|
||||
"Bash(npm install:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(node scripts/optimize-images.js:*)",
|
||||
"Bash(node scripts/optimize-images.cjs:*)",
|
||||
"Skill(frontend-design)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -2,22 +2,22 @@ import { motion } from 'framer-motion';
|
|||
import { useMemo } from 'react';
|
||||
|
||||
const BackgroundAnimations = () => {
|
||||
// Reduced particles for better performance (30 -> 12)
|
||||
// Particles with better visibility (increased opacity and size)
|
||||
const particles = useMemo(() => {
|
||||
return Array.from({ length: 12 }, (_, i) => ({
|
||||
return Array.from({ length: 18 }, (_, i) => ({
|
||||
id: i,
|
||||
x: Math.random() * 100,
|
||||
y: Math.random() * 100,
|
||||
size: Math.random() * 2 + 1,
|
||||
duration: Math.random() * 12 + 8,
|
||||
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.5 + 0.2,
|
||||
opacity: Math.random() * 0.4 + 0.5, // Much higher opacity (0.5-0.9)
|
||||
}));
|
||||
}, []);
|
||||
|
||||
// Reduced circuit nodes for performance (12 -> 6)
|
||||
// Circuit nodes for tech effect
|
||||
const circuitNodes = useMemo(() => {
|
||||
return Array.from({ length: 6 }, (_, i) => ({
|
||||
return Array.from({ length: 8 }, (_, i) => ({
|
||||
id: i,
|
||||
x: Math.random() * 80 + 10,
|
||||
y: Math.random() * 80 + 10,
|
||||
|
|
@ -25,10 +25,10 @@ const BackgroundAnimations = () => {
|
|||
}));
|
||||
}, []);
|
||||
|
||||
// Reduced connection lines (half as many)
|
||||
// Connection lines between nodes
|
||||
const connectionLines = useMemo(() => {
|
||||
const lines = [];
|
||||
for (let i = 0; i < circuitNodes.length - 1; i += 2) {
|
||||
for (let i = 0; i < circuitNodes.length - 1; i++) {
|
||||
if (i + 1 < circuitNodes.length) {
|
||||
lines.push({
|
||||
id: i,
|
||||
|
|
@ -44,72 +44,106 @@ const BackgroundAnimations = () => {
|
|||
|
||||
return (
|
||||
<div className="absolute inset-0 overflow-hidden pointer-events-none" style={{ willChange: 'transform' }}>
|
||||
{/* Simplified Static Grid Background - no animation for better performance */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-30"
|
||||
{/* Animated Grid Background */}
|
||||
<motion.div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(to right, rgba(51, 102, 255, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 102, 255, 0.03) 1px, transparent 1px)
|
||||
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: '80px 80px',
|
||||
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 - optimized */}
|
||||
<svg className="absolute inset-0 w-full h-full" style={{ opacity: 0.5, willChange: 'transform' }}>
|
||||
{/* SVG Container for Lines and Nodes */}
|
||||
<svg className="absolute inset-0 w-full h-full" style={{ willChange: 'transform' }}>
|
||||
|
||||
{/* Simplified Connection Lines - static for better performance */}
|
||||
{/* Animated Connection Lines */}
|
||||
{connectionLines.map((line) => (
|
||||
<line
|
||||
<motion.line
|
||||
key={line.id}
|
||||
x1={`${line.x1}%`}
|
||||
y1={`${line.y1}%`}
|
||||
x2={`${line.x2}%`}
|
||||
y2={`${line.y2}%`}
|
||||
stroke="rgba(51, 102, 255, 0.2)"
|
||||
strokeWidth="1"
|
||||
opacity="0.4"
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Reduced Vertical Data Streams (8 -> 4) */}
|
||||
{[...Array(4)].map((_, i) => (
|
||||
<motion.line
|
||||
key={`vertical-${i}`}
|
||||
x1={`${15 + i * 25}%`}
|
||||
y1="0%"
|
||||
x2={`${15 + i * 25}%`}
|
||||
y2="100%"
|
||||
stroke="rgba(51, 102, 255, 0.15)"
|
||||
strokeWidth="1"
|
||||
strokeDasharray="10 20"
|
||||
initial={{ strokeDashoffset: 0 }}
|
||||
animate={{ strokeDashoffset: 100 }}
|
||||
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={{
|
||||
duration: 4,
|
||||
repeat: Infinity,
|
||||
ease: "linear",
|
||||
delay: i * 0.5,
|
||||
pathLength: { duration: 2, delay: line.id * 0.3 },
|
||||
opacity: { duration: 3, repeat: Infinity, ease: "easeInOut" },
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Simplified Circuit Nodes - reduced animation */}
|
||||
{/* 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}>
|
||||
{/* Core node with simple pulse */}
|
||||
{/* Pulse ring */}
|
||||
<motion.circle
|
||||
cx={`${node.x}%`}
|
||||
cy={`${node.y}%`}
|
||||
r="2.5"
|
||||
fill="#3366ff"
|
||||
r="6"
|
||||
fill="none"
|
||||
stroke="#3366ff"
|
||||
strokeWidth="1"
|
||||
animate={{
|
||||
opacity: [0.6, 1, 0.6],
|
||||
r: [6, 12, 6],
|
||||
opacity: [0.8, 0, 0.8],
|
||||
}}
|
||||
transition={{
|
||||
duration: 3,
|
||||
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",
|
||||
|
|
@ -119,7 +153,7 @@ const BackgroundAnimations = () => {
|
|||
))}
|
||||
</svg>
|
||||
|
||||
{/* Optimized Floating Data Particles with GPU acceleration */}
|
||||
{/* Floating Data Particles - highly visible */}
|
||||
{particles.map((particle) => (
|
||||
<motion.div
|
||||
key={particle.id}
|
||||
|
|
@ -129,13 +163,12 @@ const BackgroundAnimations = () => {
|
|||
height: `${particle.size}px`,
|
||||
left: `${particle.x}%`,
|
||||
top: `${particle.y}%`,
|
||||
opacity: particle.opacity,
|
||||
boxShadow: '0 0 6px rgba(51, 102, 255, 0.6)',
|
||||
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, -600],
|
||||
opacity: [0, particle.opacity, 0],
|
||||
y: [0, -500],
|
||||
opacity: [0, particle.opacity, particle.opacity, 0],
|
||||
}}
|
||||
transition={{
|
||||
duration: particle.duration,
|
||||
|
|
@ -146,24 +179,35 @@ const BackgroundAnimations = () => {
|
|||
/>
|
||||
))}
|
||||
|
||||
{/* Simplified Static Scanline Effect - no animation */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-20 pointer-events-none"
|
||||
|
||||
|
||||
{/* 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.02) 2px,
|
||||
rgba(51, 102, 255, 0.02) 4px
|
||||
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",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Reduced Radial Glows (3 -> 2) with simpler animation */}
|
||||
{/* Radial Glows */}
|
||||
{[
|
||||
{ x: 25, y: 40 },
|
||||
{ x: 75, y: 60 },
|
||||
{ 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}`}
|
||||
|
|
@ -171,28 +215,28 @@ const BackgroundAnimations = () => {
|
|||
style={{
|
||||
left: `${pos.x}%`,
|
||||
top: `${pos.y}%`,
|
||||
width: '180px',
|
||||
height: '180px',
|
||||
background: 'radial-gradient(circle, rgba(51, 102, 255, 0.12) 0%, transparent 70%)',
|
||||
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.15, 1],
|
||||
opacity: [0.4, 0.6, 0.4],
|
||||
scale: [1, 1.3, 1],
|
||||
opacity: [0.5, 0.8, 0.5],
|
||||
}}
|
||||
transition={{
|
||||
duration: 6,
|
||||
duration: 5,
|
||||
repeat: Infinity,
|
||||
delay: i * 2,
|
||||
delay: i * 1.5,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Static Corner Accent Glows - no blur for better performance */}
|
||||
<div className="absolute top-0 left-0 w-64 h-64 bg-gradient-to-br from-neon/8 to-transparent rounded-full opacity-40 pointer-events-none" />
|
||||
<div className="absolute bottom-0 right-0 w-80 h-80 bg-gradient-to-tl from-neon/8 to-transparent rounded-full opacity-40 pointer-events-none" />
|
||||
{/* 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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue