diff options
Diffstat (limited to 'ui/src/lib/effects/ConstellationEffect.ts')
| -rw-r--r-- | ui/src/lib/effects/ConstellationEffect.ts | 129 |
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(); + } } |