TRUTHLENSAI / web_app /frontend /src /components /NeuralBackground.tsx
gregorio
feat: initial clean project setup (root-level)
3cb3dcd
Raw
History Blame Contribute Delete
2.66 kB
import React, { useEffect, useRef } from 'react';
const NeuralBackground: React.FC = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let animationFrameId: number;
let particles: Particle[] = [];
const resize = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
class Particle {
x: number; y: number; vx: number; vy: number;
constructor() {
this.x = Math.random() * canvas!.width;
this.y = Math.random() * canvas!.height;
this.vx = (Math.random() - 0.5) * 0.4;
this.vy = (Math.random() - 0.5) * 0.4;
}
update() {
this.x += this.vx;
this.y += this.vy;
if (this.x < 0 || this.x > canvas!.width) this.vx *= -1;
if (this.y < 0 || this.y > canvas!.height) this.vy *= -1;
}
draw() {
ctx!.beginPath();
ctx!.arc(this.x, this.y, 1.2, 0, Math.PI * 2);
ctx!.fillStyle = 'rgba(99, 102, 241, 0.4)';
ctx!.fill();
}
}
const init = () => {
particles = Array.from({ length: 100 }, () => new Particle());
};
const drawLines = () => {
for (let i = 0; i < particles.length; i++) {
for (let j = i + 1; j < particles.length; j++) {
const dx = particles[i].x - particles[j].x;
const dy = particles[i].y - particles[j].y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 150) {
ctx!.beginPath();
ctx!.strokeStyle = `rgba(99, 102, 241, ${0.15 * (1 - dist / 150)})`;
ctx!.lineWidth = 0.8;
ctx!.moveTo(particles[i].x, particles[i].y);
ctx!.lineTo(particles[j].x, particles[j].y);
ctx!.stroke();
}
}
}
};
const render = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
particles.forEach(p => {
p.update();
p.draw();
});
drawLines();
animationFrameId = requestAnimationFrame(render);
};
window.addEventListener('resize', resize);
resize();
init();
render();
return () => {
window.removeEventListener('resize', resize);
cancelAnimationFrame(animationFrameId);
};
}, []);
return (
<canvas
ref={canvasRef}
style={{
position: 'fixed',
top: 0,
left: 0,
zIndex: -1,
background: 'transparent',
pointerEvents: 'none'
}}
/>
);
};
export default NeuralBackground;