CodebaseAi commited on
Commit
9810f34
·
1 Parent(s): da24067

Less Lgging

Browse files
frontend/src/components/ConstellationBackground.jsx CHANGED
@@ -5,81 +5,106 @@ export default function ConstellationBackground() {
5
 
6
  useEffect(() => {
7
  const canvas = canvasRef.current;
8
- const ctx = canvas.getContext("2d");
9
 
10
  let particles = [];
11
- const count = 140; // number of stars
 
 
 
 
 
12
 
13
- // resize canvas
14
  function resize() {
15
  canvas.width = window.innerWidth;
16
  canvas.height = window.innerHeight;
 
17
  }
18
- resize();
19
- window.addEventListener("resize", resize);
20
 
21
- // create particles
22
- for (let i = 0; i < count; i++) {
23
- particles.push({
24
- x: Math.random() * canvas.width,
25
- y: Math.random() * canvas.height,
26
- vx: (Math.random() - 0.5) * 0.3,
27
- vy: (Math.random() - 0.5) * 0.3,
28
- size: Math.random() * 2 + 1,
29
- });
 
 
30
  }
31
 
32
- // animation loop
 
 
33
  function animate() {
34
- ctx.clearRect(0, 0, canvas.width, canvas.height);
 
 
 
35
 
36
- // draw particles
37
- particles.forEach((p) => {
 
38
  p.x += p.vx;
39
  p.y += p.vy;
40
 
41
- // soft bounce
42
  if (p.x < 0 || p.x > canvas.width) p.vx *= -1;
43
  if (p.y < 0 || p.y > canvas.height) p.vy *= -1;
44
 
45
  ctx.beginPath();
46
  ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
47
- ctx.fillStyle = "rgba(0, 220, 255, 0.9)";
48
- ctx.shadowBlur = 10;
49
- ctx.shadowColor = "#66e0ff";
 
 
 
 
 
50
  ctx.fill();
51
- });
 
52
 
53
- // draw connecting lines
 
54
  for (let i = 0; i < count; i++) {
55
  for (let j = i + 1; j < count; j++) {
56
  const a = particles[i];
57
  const b = particles[j];
58
- const dist = Math.hypot(a.x - b.x, a.y - b.y);
59
-
60
- if (dist < 140) {
61
- ctx.strokeStyle = `rgba(120, 255, 255, ${1 - dist / 140})`;
62
- ctx.lineWidth = 0.7;
63
- ctx.beginPath();
64
- ctx.moveTo(a.x, a.y);
65
- ctx.lineTo(b.x, b.y);
66
- ctx.stroke();
 
 
 
 
 
67
  }
68
  }
69
  }
70
 
71
- requestAnimationFrame(animate);
72
  }
73
 
74
  animate();
75
 
76
- return () => window.removeEventListener("resize", resize);
 
 
 
77
  }, []);
78
 
79
  return (
80
  <canvas
81
  ref={canvasRef}
82
- className="fixed inset-0 -z-10 pointer-events-none"
83
  />
84
  );
85
  }
 
5
 
6
  useEffect(() => {
7
  const canvas = canvasRef.current;
8
+ const ctx = canvas.getContext("2d", { alpha: false }); // Optimization: No alpha channel if background is solid
9
 
10
  let particles = [];
11
+ let animationFrameId;
12
+
13
+ // Performance Tweak: Detection
14
+ const isMobile = window.innerWidth < 768;
15
+ const count = isMobile ? 40 : 120; // Drastically reduce stars on mobile
16
+ const connectionDist = isMobile ? 90 : 140; // Shorter lines on mobile
17
 
 
18
  function resize() {
19
  canvas.width = window.innerWidth;
20
  canvas.height = window.innerHeight;
21
+ initParticles(); // Re-init so stars aren't lost on rotation
22
  }
 
 
23
 
24
+ function initParticles() {
25
+ particles = [];
26
+ for (let i = 0; i < count; i++) {
27
+ particles.push({
28
+ x: Math.random() * canvas.width,
29
+ y: Math.random() * canvas.height,
30
+ vx: (Math.random() - 0.5) * (isMobile ? 0.2 : 0.3),
31
+ vy: (Math.random() - 0.5) * (isMobile ? 0.2 : 0.3),
32
+ size: Math.random() * 1.5 + 1,
33
+ });
34
+ }
35
  }
36
 
37
+ window.addEventListener("resize", resize);
38
+ resize();
39
+
40
  function animate() {
41
+ // Use a slightly opaque clear to create a faint trail effect if desired,
42
+ // or standard clear for performance
43
+ ctx.fillStyle = "#020617";
44
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
45
 
46
+ // 1. Update and Draw Particles
47
+ for (let i = 0; i < count; i++) {
48
+ const p = particles[i];
49
  p.x += p.vx;
50
  p.y += p.vy;
51
 
 
52
  if (p.x < 0 || p.x > canvas.width) p.vx *= -1;
53
  if (p.y < 0 || p.y > canvas.height) p.vy *= -1;
54
 
55
  ctx.beginPath();
56
  ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
57
+ ctx.fillStyle = "rgba(0, 220, 255, 0.8)";
58
+
59
+ // PERF: Disable expensive ShadowBlur on mobile
60
+ if (!isMobile) {
61
+ ctx.shadowBlur = 8;
62
+ ctx.shadowColor = "#66e0ff";
63
+ }
64
+
65
  ctx.fill();
66
+ if (!isMobile) ctx.shadowBlur = 0; // Reset for lines
67
+ }
68
 
69
+ // 2. Draw Lines (The "lag" part)
70
+ ctx.lineWidth = 0.5;
71
  for (let i = 0; i < count; i++) {
72
  for (let j = i + 1; j < count; j++) {
73
  const a = particles[i];
74
  const b = particles[j];
75
+
76
+ // Optimization: Check simple X/Y distance before doing heavy Math.hypot
77
+ const dx = a.x - b.x;
78
+ const dy = a.y - b.y;
79
+
80
+ if (Math.abs(dx) < connectionDist && Math.abs(dy) < connectionDist) {
81
+ const dist = Math.sqrt(dx * dx + dy * dy);
82
+ if (dist < connectionDist) {
83
+ ctx.strokeStyle = `rgba(120, 255, 255, ${1 - dist / connectionDist})`;
84
+ ctx.beginPath();
85
+ ctx.moveTo(a.x, a.y);
86
+ ctx.lineTo(b.x, b.y);
87
+ ctx.stroke();
88
+ }
89
  }
90
  }
91
  }
92
 
93
+ animationFrameId = requestAnimationFrame(animate);
94
  }
95
 
96
  animate();
97
 
98
+ return () => {
99
+ window.removeEventListener("resize", resize);
100
+ cancelAnimationFrame(animationFrameId);
101
+ };
102
  }, []);
103
 
104
  return (
105
  <canvas
106
  ref={canvasRef}
107
+ className="fixed inset-0 -z-20 pointer-events-none bg-[#020617]"
108
  />
109
  );
110
  }