aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ui/src/lib/effects/ConstellationEffect.ts
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/lib/effects/ConstellationEffect.ts')
-rw-r--r--ui/src/lib/effects/ConstellationEffect.ts129
1 files changed, 64 insertions, 65 deletions
diff --git a/ui/src/lib/effects/ConstellationEffect.ts b/ui/src/lib/effects/ConstellationEffect.ts
index 2cc702e..d2db529 100644
--- a/ui/src/lib/effects/ConstellationEffect.ts
+++ b/ui/src/lib/effects/ConstellationEffect.ts
@@ -1,4 +1,3 @@
-
export class ConstellationEffect {
private canvas: HTMLCanvasElement;
private ctx: CanvasRenderingContext2D;
@@ -17,7 +16,7 @@ export class ConstellationEffect {
constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas;
this.ctx = canvas.getContext("2d", { alpha: true })!;
-
+
// Bind methods
this.animate = this.animate.bind(this);
this.handleMouseMove = this.handleMouseMove.bind(this);
@@ -25,7 +24,7 @@ export class ConstellationEffect {
// Initial setup
this.resize(window.innerWidth, window.innerHeight);
this.initParticles();
-
+
// Mouse interaction
window.addEventListener("mousemove", this.handleMouseMove);
@@ -44,10 +43,10 @@ export class ConstellationEffect {
this.canvas.style.height = `${height}px`;
this.ctx.scale(dpr, dpr);
-
+
// Re-initialize if screen size changes significantly to maintain density
if (this.particles.length === 0) {
- this.initParticles();
+ this.initParticles();
}
}
@@ -71,9 +70,9 @@ export class ConstellationEffect {
animate() {
this.ctx.clearRect(0, 0, this.width, this.height);
-
+
// Update and draw particles
- this.particles.forEach(p => {
+ this.particles.forEach((p) => {
p.update(this.width, this.height);
p.draw(this.ctx);
});
@@ -86,41 +85,41 @@ export class ConstellationEffect {
private drawConnections() {
this.ctx.lineWidth = 1;
-
+
for (let i = 0; i < this.particles.length; i++) {
- const p1 = this.particles[i];
-
- // Connect to mouse if close
- const distMouse = Math.hypot(p1.x - this.mouseX, p1.y - this.mouseY);
- if (distMouse < this.connectionDistance + 50) {
- const alpha = 1 - (distMouse / (this.connectionDistance + 50));
- this.ctx.strokeStyle = `rgba(255, 255, 255, ${alpha * 0.4})`; // Brighter near mouse
- this.ctx.beginPath();
- this.ctx.moveTo(p1.x, p1.y);
- this.ctx.lineTo(this.mouseX, this.mouseY);
- this.ctx.stroke();
-
- // Gently attract to mouse
- if (distMouse > 10) {
- p1.x += (this.mouseX - p1.x) * 0.005;
- p1.y += (this.mouseY - p1.y) * 0.005;
- }
+ const p1 = this.particles[i];
+
+ // Connect to mouse if close
+ const distMouse = Math.hypot(p1.x - this.mouseX, p1.y - this.mouseY);
+ if (distMouse < this.connectionDistance + 50) {
+ const alpha = 1 - distMouse / (this.connectionDistance + 50);
+ this.ctx.strokeStyle = `rgba(255, 255, 255, ${alpha * 0.4})`; // Brighter near mouse
+ this.ctx.beginPath();
+ this.ctx.moveTo(p1.x, p1.y);
+ this.ctx.lineTo(this.mouseX, this.mouseY);
+ this.ctx.stroke();
+
+ // Gently attract to mouse
+ if (distMouse > 10) {
+ p1.x += (this.mouseX - p1.x) * 0.005;
+ p1.y += (this.mouseY - p1.y) * 0.005;
}
-
- // Connect to other particles
- for (let j = i + 1; j < this.particles.length; j++) {
- const p2 = this.particles[j];
- const dist = Math.hypot(p1.x - p2.x, p1.y - p2.y);
-
- if (dist < this.connectionDistance) {
- const alpha = 1 - (dist / this.connectionDistance);
- this.ctx.strokeStyle = `rgba(255, 255, 255, ${alpha * 0.15})`;
- this.ctx.beginPath();
- this.ctx.moveTo(p1.x, p1.y);
- this.ctx.lineTo(p2.x, p2.y);
- this.ctx.stroke();
- }
+ }
+
+ // Connect to other particles
+ for (let j = i + 1; j < this.particles.length; j++) {
+ const p2 = this.particles[j];
+ const dist = Math.hypot(p1.x - p2.x, p1.y - p2.y);
+
+ if (dist < this.connectionDistance) {
+ const alpha = 1 - dist / this.connectionDistance;
+ this.ctx.strokeStyle = `rgba(255, 255, 255, ${alpha * 0.15})`;
+ this.ctx.beginPath();
+ this.ctx.moveTo(p1.x, p1.y);
+ this.ctx.lineTo(p2.x, p2.y);
+ this.ctx.stroke();
}
+ }
}
}
@@ -131,33 +130,33 @@ export class ConstellationEffect {
}
class Particle {
- x: number;
- y: number;
- vx: number;
- vy: number;
- size: number;
-
- constructor(w: number, h: number, speed: number) {
- this.x = Math.random() * w;
- this.y = Math.random() * h;
- this.vx = (Math.random() - 0.5) * speed;
- this.vy = (Math.random() - 0.5) * speed;
- this.size = Math.random() * 2 + 1;
- }
+ x: number;
+ y: number;
+ vx: number;
+ vy: number;
+ size: number;
+
+ constructor(w: number, h: number, speed: number) {
+ this.x = Math.random() * w;
+ this.y = Math.random() * h;
+ this.vx = (Math.random() - 0.5) * speed;
+ this.vy = (Math.random() - 0.5) * speed;
+ this.size = Math.random() * 2 + 1;
+ }
- update(w: number, h: number) {
- this.x += this.vx;
- this.y += this.vy;
+ update(w: number, h: number) {
+ this.x += this.vx;
+ this.y += this.vy;
- // Bounce off walls
- if (this.x < 0 || this.x > w) this.vx *= -1;
- if (this.y < 0 || this.y > h) this.vy *= -1;
- }
+ // Bounce off walls
+ if (this.x < 0 || this.x > w) this.vx *= -1;
+ if (this.y < 0 || this.y > h) this.vy *= -1;
+ }
- draw(ctx: CanvasRenderingContext2D) {
- ctx.fillStyle = "rgba(255, 255, 255, 0.4)";
- ctx.beginPath();
- ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
- ctx.fill();
- }
+ draw(ctx: CanvasRenderingContext2D) {
+ ctx.fillStyle = "rgba(255, 255, 255, 0.4)";
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
+ ctx.fill();
+ }
}