Enhance particle background with more characters and ambient effects
Update particle background to increase particle spawn rate on mouse move, add ambient particle spawning when idle, and increase max particle limit. Replit-Commit-Author: Agent Replit-Commit-Session-Id: beb495f8-3942-42fd-9d1b-db8f707d320f Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: c2b88424-5180-488e-b61b-c1eb8bc69a5c Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/804258ec-282b-434a-9b89-a7ccc1690e42/beb495f8-3942-42fd-9d1b-db8f707d320f/3Fb2Xuc Replit-Helium-Checkpoint-Created: true
This commit is contained in:
@@ -24,8 +24,9 @@ interface Particle {
|
||||
function ParticleBackground() {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
const particlesRef = useRef<Particle[]>([]);
|
||||
const mouseRef = useRef({ x: 0, y: 0 });
|
||||
const mouseRef = useRef({ x: window.innerWidth / 2, y: window.innerHeight / 2 });
|
||||
const animationRef = useRef<number>();
|
||||
const frameCountRef = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = canvasRef.current;
|
||||
@@ -51,21 +52,22 @@ function ParticleBackground() {
|
||||
"#cba6f7",
|
||||
];
|
||||
|
||||
const createParticle = (x: number, y: number): Particle => {
|
||||
const createParticle = (x: number, y: number, isAmbient = false): Particle => {
|
||||
const angle = Math.random() * Math.PI * 2;
|
||||
const speed = Math.random() * 2 + 1;
|
||||
const speed = isAmbient ? Math.random() * 0.5 + 0.2 : Math.random() * 2 + 1;
|
||||
const color = colors[Math.floor(Math.random() * colors.length)];
|
||||
const spread = isAmbient ? 200 : 120;
|
||||
return {
|
||||
x: x + (Math.random() - 0.5) * 100,
|
||||
y: y + (Math.random() - 0.5) * 100,
|
||||
x: x + (Math.random() - 0.5) * spread,
|
||||
y: y + (Math.random() - 0.5) * spread,
|
||||
char: CHARACTERS[Math.floor(Math.random() * CHARACTERS.length)],
|
||||
opacity: Math.random() * 0.8 + 0.2,
|
||||
opacity: isAmbient ? Math.random() * 0.4 + 0.1 : Math.random() * 0.8 + 0.2,
|
||||
targetX: x,
|
||||
targetY: y,
|
||||
vx: Math.cos(angle) * speed,
|
||||
vy: Math.sin(angle) * speed,
|
||||
life: 0,
|
||||
maxLife: Math.random() * 60 + 40,
|
||||
maxLife: isAmbient ? Math.random() * 120 + 80 : Math.random() * 80 + 50,
|
||||
size: Math.random() * 10 + 12,
|
||||
color,
|
||||
};
|
||||
@@ -74,8 +76,8 @@ function ParticleBackground() {
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
mouseRef.current = { x: e.clientX, y: e.clientY };
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (particlesRef.current.length < 200) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (particlesRef.current.length < 400) {
|
||||
particlesRef.current.push(createParticle(e.clientX, e.clientY));
|
||||
}
|
||||
}
|
||||
@@ -84,34 +86,48 @@ function ParticleBackground() {
|
||||
const animate = () => {
|
||||
ctx.fillStyle = "#000000";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
frameCountRef.current++;
|
||||
|
||||
if (frameCountRef.current % 3 === 0 && particlesRef.current.length < 400) {
|
||||
const mx = mouseRef.current.x;
|
||||
const my = mouseRef.current.y;
|
||||
particlesRef.current.push(createParticle(mx, my, true));
|
||||
}
|
||||
|
||||
if (frameCountRef.current % 8 === 0 && particlesRef.current.length < 400) {
|
||||
const rx = Math.random() * canvas.width;
|
||||
const ry = Math.random() * canvas.height;
|
||||
particlesRef.current.push(createParticle(rx, ry, true));
|
||||
}
|
||||
|
||||
particlesRef.current = particlesRef.current.filter((p) => {
|
||||
p.life++;
|
||||
|
||||
const dx = mouseRef.current.x - p.x;
|
||||
const dy = mouseRef.current.y - p.y;
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
const distance = Math.sqrt(dx * dx + dy * dy) || 1;
|
||||
|
||||
if (distance < 150) {
|
||||
const force = (150 - distance) / 150;
|
||||
p.vx += (dx / distance) * force * 0.3;
|
||||
p.vy += (dy / distance) * force * 0.3;
|
||||
if (distance < 200) {
|
||||
const force = (200 - distance) / 200;
|
||||
p.vx += (dx / distance) * force * 0.4;
|
||||
p.vy += (dy / distance) * force * 0.4;
|
||||
}
|
||||
|
||||
p.vx *= 0.96;
|
||||
p.vy *= 0.96;
|
||||
p.vx *= 0.97;
|
||||
p.vy *= 0.97;
|
||||
|
||||
p.x += p.vx;
|
||||
p.y += p.vy;
|
||||
|
||||
const lifeRatio = p.life / p.maxLife;
|
||||
const fadeOpacity = lifeRatio < 0.2
|
||||
? lifeRatio * 5
|
||||
const fadeOpacity = lifeRatio < 0.15
|
||||
? lifeRatio * 6.67
|
||||
: lifeRatio > 0.7
|
||||
? (1 - lifeRatio) * 3.33
|
||||
: 1;
|
||||
|
||||
const distanceOpacity = Math.max(0, 1 - distance / 300);
|
||||
const distanceOpacity = Math.max(0.15, 1 - distance / 400);
|
||||
const finalOpacity = p.opacity * fadeOpacity * distanceOpacity;
|
||||
|
||||
if (finalOpacity > 0.01) {
|
||||
|
||||
Reference in New Issue
Block a user