ProjectGenesis commited on
Commit
9cfda53
·
verified ·
1 Parent(s): b550ef8

Change the particle background into an Interactive Particle Network background with animations.

Browse files
Files changed (2) hide show
  1. script.js +107 -58
  2. style.css +2 -2
script.js CHANGED
@@ -76,29 +76,39 @@ function createParticleNetwork() {
76
  constructor() {
77
  this.x = Math.random() * canvas.width;
78
  this.y = Math.random() * canvas.height;
79
- this.size = Math.random() * 3 + 1;
80
  this.baseX = this.x;
81
  this.baseY = this.y;
82
- this.density = (Math.random() * 30) + 1;
83
  this.color = this.getRandomColor();
 
 
 
 
 
 
 
84
  }
85
 
86
  getRandomColor() {
87
- const colors = [
88
- 'rgba(15, 240, 252, 0.8)', // neon blue
89
- 'rgba(255, 0, 255, 0.8)', // neon magenta
90
- 'rgba(255, 255, 0, 0.8)', // neon yellow
91
- 'rgba(0, 255, 255, 0.8)', // cyan
92
- 'rgba(255, 255, 255, 0.8)' // white
93
- ];
94
- return colors[Math.floor(Math.random() * colors.length)];
95
  }
96
 
97
  draw() {
 
 
 
 
 
 
 
 
98
  ctx.beginPath();
99
  ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
100
- ctx.closePath();
101
- ctx.fillStyle = this.color;
102
  ctx.fill();
103
 
104
  // Add glow effect
@@ -107,44 +117,55 @@ function createParticleNetwork() {
107
  }
108
 
109
  update() {
110
- // Mouse interaction
111
- const dx = mouse.x - this.x;
112
- const dy = mouse.y - this.y;
113
- const distance = Math.sqrt(dx * dx + dy * dy);
114
- const forceDirectionX = dx / distance;
115
- const forceDirectionY = dy / distance;
116
- const maxDistance = mouse.radius;
117
- let force = (maxDistance - distance) / maxDistance;
118
-
119
- if (force < 0) force = 0;
120
-
121
- const directionX = forceDirectionX * force * this.density * 0.6;
122
- const directionY = forceDirectionY * force * this.density * 0.6;
123
 
124
- if (distance < mouse.radius + this.size) {
125
- this.x -= directionX;
126
- this.y -= directionY;
127
- } else {
128
- // Return to original position with easing
129
- if (this.x !== this.baseX) {
130
- const dx = this.x - this.baseX;
131
- this.x -= dx / 10;
132
- }
133
- if (this.y !== this.baseY) {
134
- const dy = this.y - this.baseY;
135
- this.y -= dy / 10;
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
 
 
 
 
137
  }
138
 
139
  // Add some random movement
140
- this.x += (Math.random() - 0.5) * 0.5;
141
- this.y += (Math.random() - 0.5) * 0.5;
 
 
 
 
142
  }
143
  }
144
 
145
  // Create particles
146
  const particles = [];
147
- const particleCount = Math.floor((canvas.width * canvas.height) / 9000);
148
 
149
  for (let i = 0; i < particleCount; i++) {
150
  particles.push(new Particle());
@@ -158,46 +179,64 @@ function createParticleNetwork() {
158
  const dy = particles[a].y - particles[b].y;
159
  const distance = Math.sqrt(dx * dx + dy * dy);
160
 
161
- if (distance < 100) {
162
- const opacity = 1 - distance / 100;
163
- ctx.strokeStyle = `rgba(15, 240, 252, ${opacity * 0.5})`;
164
- ctx.lineWidth = 1;
 
 
 
 
 
 
 
 
 
 
165
  ctx.beginPath();
166
  ctx.moveTo(particles[a].x, particles[a].y);
167
  ctx.lineTo(particles[b].x, particles[b].y);
168
  ctx.stroke();
169
-
170
- // Alternate line color
171
- if (distance < 50) {
172
- ctx.strokeStyle = `rgba(255, 0, 255, ${opacity * 0.3})`;
173
- ctx.beginPath();
174
- ctx.moveTo(particles[a].x, particles[a].y);
175
- ctx.lineTo(particles[b].x, particles[b].y);
176
- ctx.stroke();
177
- }
178
  }
179
  }
180
  }
181
  }
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  // Animation loop
184
  function animate() {
185
  ctx.clearRect(0, 0, canvas.width, canvas.height);
186
 
 
 
 
 
 
 
187
  // Draw particles
188
  for (let i = 0; i < particles.length; i++) {
189
  particles[i].draw();
190
  particles[i].update();
191
  }
192
 
193
- // Connect particles
194
- connect();
195
-
196
  requestAnimationFrame(animate);
197
  }
198
 
199
  // Handle resize
200
- window.addEventListener('resize', () => {
201
  canvas.width = container.offsetWidth;
202
  canvas.height = container.offsetHeight;
203
 
@@ -206,8 +245,18 @@ function createParticleNetwork() {
206
  for (let i = 0; i < particleCount; i++) {
207
  particles.push(new Particle());
208
  }
209
- });
 
 
210
 
211
  // Start animation
212
  animate();
 
 
 
 
 
 
 
 
213
  }
 
76
  constructor() {
77
  this.x = Math.random() * canvas.width;
78
  this.y = Math.random() * canvas.height;
79
+ this.size = Math.random() * 2 + 1;
80
  this.baseX = this.x;
81
  this.baseY = this.y;
82
+ this.density = (Math.random() * 50) + 10;
83
  this.color = this.getRandomColor();
84
+ this.velocity = {
85
+ x: (Math.random() - 0.5) * 0.5,
86
+ y: (Math.random() - 0.5) * 0.5
87
+ };
88
+ this.angle = Math.random() * Math.PI * 2;
89
+ this.orbitRadius = Math.random() * 50 + 20;
90
+ this.orbitSpeed = Math.random() * 0.02 + 0.005;
91
  }
92
 
93
  getRandomColor() {
94
+ const hue = Math.random() * 360;
95
+ const saturation = 80 + Math.random() * 20;
96
+ const lightness = 50 + Math.random() * 20;
97
+ return `hsla(${hue}, ${saturation}%, ${lightness}%, 0.8)`;
 
 
 
 
98
  }
99
 
100
  draw() {
101
+ // Create gradient for each particle
102
+ const gradient = ctx.createRadialGradient(
103
+ this.x, this.y, 0,
104
+ this.x, this.y, this.size
105
+ );
106
+ gradient.addColorStop(0, this.color);
107
+ gradient.addColorStop(1, 'transparent');
108
+
109
  ctx.beginPath();
110
  ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
111
+ ctx.fillStyle = gradient;
 
112
  ctx.fill();
113
 
114
  // Add glow effect
 
117
  }
118
 
119
  update() {
120
+ // Orbital movement
121
+ this.angle += this.orbitSpeed;
122
+ this.baseX = canvas.width/2 + Math.cos(this.angle) * this.orbitRadius;
123
+ this.baseY = canvas.height/2 + Math.sin(this.angle) * this.orbitRadius;
 
 
 
 
 
 
 
 
 
124
 
125
+ // Mouse interaction
126
+ if (mouse.x && mouse.y) {
127
+ const dx = mouse.x - this.x;
128
+ const dy = mouse.y - this.y;
129
+ const distance = Math.sqrt(dx * dx + dy * dy);
130
+ const maxDistance = mouse.radius;
131
+
132
+ if (distance < maxDistance) {
133
+ const forceDirectionX = dx / distance;
134
+ const forceDirectionY = dy / distance;
135
+ const force = (maxDistance - distance) / maxDistance;
136
+ const directionX = forceDirectionX * force * this.density * 0.6;
137
+ const directionY = forceDirectionY * force * this.density * 0.6;
138
+
139
+ this.x -= directionX;
140
+ this.y -= directionY;
141
+ } else {
142
+ // Return to original position with easing
143
+ if (this.x !== this.baseX) {
144
+ this.x += (this.baseX - this.x) / 20;
145
+ }
146
+ if (this.y !== this.baseY) {
147
+ this.y += (this.baseY - this.y) / 20;
148
+ }
149
  }
150
+ } else {
151
+ // Continue orbiting if mouse not present
152
+ this.x += (this.baseX - this.x) / 20;
153
+ this.y += (this.baseY - this.y) / 20;
154
  }
155
 
156
  // Add some random movement
157
+ this.x += this.velocity.x;
158
+ this.y += this.velocity.y;
159
+
160
+ // Bounce off edges
161
+ if (this.x < 0 || this.x > canvas.width) this.velocity.x *= -1;
162
+ if (this.y < 0 || this.y > canvas.height) this.velocity.y *= -1;
163
  }
164
  }
165
 
166
  // Create particles
167
  const particles = [];
168
+ const particleCount = Math.floor((canvas.width * canvas.height) / 5000);
169
 
170
  for (let i = 0; i < particleCount; i++) {
171
  particles.push(new Particle());
 
179
  const dy = particles[a].y - particles[b].y;
180
  const distance = Math.sqrt(dx * dx + dy * dy);
181
 
182
+ if (distance < 150) {
183
+ const opacity = 1 - distance / 150;
184
+
185
+ // Create gradient for connection line
186
+ const gradient = ctx.createLinearGradient(
187
+ particles[a].x, particles[a].y,
188
+ particles[b].x, particles[b].y
189
+ );
190
+ gradient.addColorStop(0, particles[a].color);
191
+ gradient.addColorStop(1, particles[b].color);
192
+
193
+ ctx.strokeStyle = gradient;
194
+ ctx.globalAlpha = opacity * 0.3;
195
+ ctx.lineWidth = 0.5 + opacity * 1.5;
196
  ctx.beginPath();
197
  ctx.moveTo(particles[a].x, particles[a].y);
198
  ctx.lineTo(particles[b].x, particles[b].y);
199
  ctx.stroke();
200
+ ctx.globalAlpha = 1;
 
 
 
 
 
 
 
 
201
  }
202
  }
203
  }
204
  }
205
 
206
+ // Draw background
207
+ function drawBackground() {
208
+ const gradient = ctx.createRadialGradient(
209
+ canvas.width/2, canvas.height/2, 0,
210
+ canvas.width/2, canvas.height/2, Math.max(canvas.width, canvas.height)/2
211
+ );
212
+ gradient.addColorStop(0, 'rgba(5, 5, 15, 0)');
213
+ gradient.addColorStop(1, 'rgba(10, 10, 26, 1)');
214
+
215
+ ctx.fillStyle = gradient;
216
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
217
+ }
218
+
219
  // Animation loop
220
  function animate() {
221
  ctx.clearRect(0, 0, canvas.width, canvas.height);
222
 
223
+ // Draw background
224
+ drawBackground();
225
+
226
+ // Connect particles first (behind)
227
+ connect();
228
+
229
  // Draw particles
230
  for (let i = 0; i < particles.length; i++) {
231
  particles[i].draw();
232
  particles[i].update();
233
  }
234
 
 
 
 
235
  requestAnimationFrame(animate);
236
  }
237
 
238
  // Handle resize
239
+ function handleResize() {
240
  canvas.width = container.offsetWidth;
241
  canvas.height = container.offsetHeight;
242
 
 
245
  for (let i = 0; i < particleCount; i++) {
246
  particles.push(new Particle());
247
  }
248
+ }
249
+
250
+ window.addEventListener('resize', handleResize);
251
 
252
  // Start animation
253
  animate();
254
+
255
+ // Add periodic pulse effect
256
+ setInterval(() => {
257
+ particles.forEach(p => {
258
+ p.orbitSpeed = (Math.random() * 0.03 + 0.01) * (Math.random() > 0.5 ? 1 : -1);
259
+ p.orbitRadius = Math.random() * 100 + 50;
260
+ });
261
+ }, 3000);
262
  }
style.css CHANGED
@@ -257,7 +257,6 @@ box-shadow: 0 0 30px rgba(15, 240, 252, 0.5),
257
  background: radial-gradient(circle at center, #050515 0%, #0a0a1a 100%);
258
  overflow: hidden;
259
  }
260
-
261
  .cosmic-canvas {
262
  position: absolute;
263
  top: 0;
@@ -265,8 +264,9 @@ box-shadow: 0 0 30px rgba(15, 240, 252, 0.5),
265
  width: 100%;
266
  height: 100%;
267
  z-index: 1;
268
- opacity: 0.9;
269
  mix-blend-mode: screen;
 
270
  }
271
  /* Brand Logo Positioning */
272
  .brand-logo {
 
257
  background: radial-gradient(circle at center, #050515 0%, #0a0a1a 100%);
258
  overflow: hidden;
259
  }
 
260
  .cosmic-canvas {
261
  position: absolute;
262
  top: 0;
 
264
  width: 100%;
265
  height: 100%;
266
  z-index: 1;
267
+ opacity: 0.8;
268
  mix-blend-mode: screen;
269
+ pointer-events: none;
270
  }
271
  /* Brand Logo Positioning */
272
  .brand-logo {