forked from nulang-org/nulang
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHeroBackground.astro
More file actions
115 lines (98 loc) · 3.1 KB
/
Copy pathHeroBackground.astro
File metadata and controls
115 lines (98 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
---
---
<div aria-hidden="true"></div>
<script>
function initHeroBackground() {
const hero = document.querySelector('.hero');
if (!hero) return;
const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const canvas = document.createElement('canvas');
canvas.className = 'hero-bg-canvas';
hero.insertBefore(canvas, hero.firstChild);
const ctx = canvas.getContext('2d');
if (!ctx) return;
function resize() {
const dpr = window.devicePixelRatio || 1;
const w = hero.clientWidth;
const h = hero.clientHeight;
canvas.width = w * dpr;
canvas.height = h * dpr;
canvas.style.width = w + 'px';
canvas.style.height = h + 'px';
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
resize();
window.addEventListener('resize', resize);
const accent = getComputedStyle(document.documentElement).getPropertyValue('--sl-color-accent').trim() || '#3b82f6';
const W = () => hero.clientWidth;
const H = () => hero.clientHeight;
const particleCount = 60;
const particles = Array.from({ length: particleCount }, () => ({
x: Math.random() * W(),
y: Math.random() * H(),
vx: (Math.random() - 0.5) * 0.6,
vy: (Math.random() - 0.5) * 0.6,
r: 1.5 + Math.random() * 1.5,
}));
function draw() {
const w = W();
const h = H();
ctx.clearRect(0, 0, w, h);
// connections
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 < 130) {
ctx.globalAlpha = (1 - dist / 130) * 0.25;
ctx.strokeStyle = accent;
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.moveTo(particles[i].x, particles[i].y);
ctx.lineTo(particles[j].x, particles[j].y);
ctx.stroke();
}
}
}
// particles
for (const p of particles) {
ctx.globalAlpha = 0.4;
ctx.fillStyle = accent;
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
ctx.fill();
}
ctx.globalAlpha = 1;
}
function update() {
const w = W();
const h = H();
for (const p of particles) {
p.x += p.vx;
p.y += p.vy;
if (p.x < 0 || p.x > w) p.vx *= -1;
if (p.y < 0 || p.y > h) p.vy *= -1;
p.x = Math.max(0, Math.min(w, p.x));
p.y = Math.max(0, Math.min(h, p.y));
}
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
if (reducedMotion) {
draw();
} else {
loop();
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
requestIdleCallback ? requestIdleCallback(initHeroBackground) : setTimeout(initHeroBackground, 200);
});
} else {
requestIdleCallback ? requestIdleCallback(initHeroBackground) : setTimeout(initHeroBackground, 200);
}
</script>