22
33import { useEffect , useRef } from 'react'
44
5- interface Particle {
6- x : number
7- y : number
8- vx : number
9- vy : number
10- radius : number
11- }
12-
135const InteractiveBackground = ( ) => {
146 const canvasRef = useRef < HTMLCanvasElement > ( null )
157
@@ -32,99 +24,69 @@ const InteractiveBackground = () => {
3224 }
3325 window . addEventListener ( 'resize' , resize )
3426
35- // Configuration
36- const particleCount = Math . floor ( ( width * height ) / 15000 )
37- const connectionDistance = 150
38- const particles : Particle [ ] = [ ]
27+ // Vibrant Aurora Orbs
28+ const orbs = [
29+ { x : width * 0.2 , y : height * 0.2 , vx : 0.5 , vy : 0.3 , radius : width * 0.4 , color : 'rgba(0, 229, 255, 0.4)' } , // Cyan
30+ { x : width * 0.8 , y : height * 0.8 , vx : - 0.4 , vy : - 0.5 , radius : width * 0.5 , color : 'rgba(139, 92, 246, 0.4)' } , // Violet
31+ { x : width * 0.5 , y : height * 0.5 , vx : 0.3 , vy : - 0.4 , radius : width * 0.6 , color : 'rgba(217, 70, 239, 0.3)' } , // Fuchsia
32+ { x : width * 0.8 , y : height * 0.2 , vx : - 0.6 , vy : 0.4 , radius : width * 0.4 , color : 'rgba(56, 189, 248, 0.4)' } , // Light Blue
33+ ]
34+
35+ let mouseX = width / 2
36+ let mouseY = height / 2
3937
40- // Mouse interaction
41- let mouse = { x : - 1000 , y : - 1000 }
4238 const handleMouseMove = ( e : MouseEvent ) => {
43- mouse . x = e . clientX
44- mouse . y = e . clientY
45- }
46- const handleMouseLeave = ( ) => {
47- mouse . x = - 1000
48- mouse . y = - 1000
39+ mouseX = e . clientX
40+ mouseY = e . clientY
4941 }
5042 window . addEventListener ( 'mousemove' , handleMouseMove )
51- document . addEventListener ( 'mouseleave' , handleMouseLeave )
52-
53- // Init particles
54- for ( let i = 0 ; i < particleCount ; i ++ ) {
55- particles . push ( {
56- x : Math . random ( ) * width ,
57- y : Math . random ( ) * height ,
58- vx : ( Math . random ( ) - 0.5 ) * 0.5 ,
59- vy : ( Math . random ( ) - 0.5 ) * 0.5 ,
60- radius : Math . random ( ) * 1.5 + 0.5
61- } )
62- }
6343
6444 const animate = ( ) => {
65- ctx . clearRect ( 0 , 0 , width , height )
66-
67- // Draw a subtle gradient background
68- const bgGradient = ctx . createRadialGradient ( width / 2 , height / 2 , 0 , width / 2 , height / 2 , width )
69- bgGradient . addColorStop ( 0 , '#0a0a0f' )
70- bgGradient . addColorStop ( 1 , '#000000' )
71- ctx . fillStyle = bgGradient
45+ ctx . fillStyle = '#05050A' // Very dark violet/black base
7246 ctx . fillRect ( 0 , 0 , width , height )
7347
74- // Update and draw particles
75- for ( let i = 0 ; i < particles . length ; i ++ ) {
76- const p = particles [ i ]
77-
48+ // Draw and move orbs
49+ orbs . forEach ( ( orb , index ) => {
7850 // Move
79- p . x += p . vx
80- p . y += p . vy
81-
82- // Bounce off edges
83- if ( p . x < 0 || p . x > width ) p . vx *= - 1
84- if ( p . y < 0 || p . y > height ) p . vy *= - 1
85-
86- // Mouse repulsion
87- const dx = mouse . x - p . x
88- const dy = mouse . y - p . y
89- const dist = Math . sqrt ( dx * dx + dy * dy )
90- if ( dist < 100 ) {
91- const force = ( 100 - dist ) / 100
92- p . x -= ( dx / dist ) * force * 2
93- p . y -= ( dy / dist ) * force * 2
51+ orb . x += orb . vx
52+ orb . y += orb . vy
53+
54+ // Bounce gently off boundaries (with massive padding so they can go off-screen)
55+ if ( orb . x < - orb . radius || orb . x > width + orb . radius ) orb . vx *= - 1
56+ if ( orb . y < - orb . radius || orb . y > height + orb . radius ) orb . vy *= - 1
57+
58+ // Add subtle mouse attraction to the first orb (Cyan)
59+ if ( index === 0 ) {
60+ orb . x += ( mouseX - orb . x ) * 0.005
61+ orb . y += ( mouseY - orb . y ) * 0.005
9462 }
9563
96- // Draw particle
64+ // Draw gradient orb
65+ const gradient = ctx . createRadialGradient ( orb . x , orb . y , 0 , orb . x , orb . y , orb . radius )
66+ gradient . addColorStop ( 0 , orb . color )
67+ gradient . addColorStop ( 1 , 'transparent' )
68+
9769 ctx . beginPath ( )
98- ctx . arc ( p . x , p . y , p . radius , 0 , Math . PI * 2 )
99- ctx . fillStyle = 'rgba(0, 229, 255, 0.8)'
70+ ctx . arc ( orb . x , orb . y , orb . radius , 0 , Math . PI * 2 )
71+ ctx . fillStyle = gradient
10072 ctx . fill ( )
73+ } )
10174
102- // Connect particles
103- for ( let j = i + 1 ; j < particles . length ; j ++ ) {
104- const p2 = particles [ j ]
105- const dx2 = p . x - p2 . x
106- const dy2 = p . y - p2 . y
107- const dist2 = Math . sqrt ( dx2 * dx2 + dy2 * dy2 )
108-
109- if ( dist2 < connectionDistance ) {
110- ctx . beginPath ( )
111- ctx . moveTo ( p . x , p . y )
112- ctx . lineTo ( p2 . x , p2 . y )
113- const opacity = 1 - ( dist2 / connectionDistance )
114- ctx . strokeStyle = `rgba(0, 229, 255, ${ opacity * 0.2 } )`
115- ctx . lineWidth = 1
116- ctx . stroke ( )
117- }
118- }
75+ // Add a subtle grid overlay for a high-tech feel
76+ ctx . strokeStyle = 'rgba(255, 255, 255, 0.03)'
77+ ctx . lineWidth = 1
78+ const gridSize = 50
79+ for ( let x = 0 ; x < width ; x += gridSize ) {
80+ ctx . beginPath ( )
81+ ctx . moveTo ( x , 0 )
82+ ctx . lineTo ( x , height )
83+ ctx . stroke ( )
11984 }
120-
121- // Add a large glowing aura around the mouse
122- if ( mouse . x !== - 1000 ) {
123- const mouseGlow = ctx . createRadialGradient ( mouse . x , mouse . y , 0 , mouse . x , mouse . y , 200 )
124- mouseGlow . addColorStop ( 0 , 'rgba(0, 229, 255, 0.05)' )
125- mouseGlow . addColorStop ( 1 , 'transparent' )
126- ctx . fillStyle = mouseGlow
127- ctx . fillRect ( 0 , 0 , width , height )
85+ for ( let y = 0 ; y < height ; y += gridSize ) {
86+ ctx . beginPath ( )
87+ ctx . moveTo ( 0 , y )
88+ ctx . lineTo ( width , y )
89+ ctx . stroke ( )
12890 }
12991
13092 requestAnimationFrame ( animate )
@@ -135,15 +97,17 @@ const InteractiveBackground = () => {
13597 return ( ) => {
13698 window . removeEventListener ( 'resize' , resize )
13799 window . removeEventListener ( 'mousemove' , handleMouseMove )
138- document . removeEventListener ( 'mouseleave' , handleMouseLeave )
139100 }
140101 } , [ ] )
141102
142103 return (
143- < canvas
144- ref = { canvasRef }
145- className = "fixed inset-0 -z-10 pointer-events-none"
146- />
104+ < div className = "fixed inset-0 -z-10 bg-[#05050A]" >
105+ < canvas
106+ ref = { canvasRef }
107+ className = "w-full h-full object-cover"
108+ style = { { filter : 'blur(60px) saturate(150%)' } }
109+ />
110+ </ div >
147111 )
148112}
149113
0 commit comments