-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparticles.js
More file actions
79 lines (71 loc) · 2.51 KB
/
particles.js
File metadata and controls
79 lines (71 loc) · 2.51 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
// Partículas minimalistas para el hero
// Puntos azules flotando con líneas de conexión sutiles
class HeroParticles {
constructor(canvas) {
this.canvas = canvas
this.ctx = canvas.getContext('2d')
this.particles = []
this.resize()
this.init()
window.addEventListener('resize', () => { this.resize(); this.init() })
}
resize() {
this.canvas.width = this.canvas.offsetWidth
this.canvas.height = this.canvas.offsetHeight
}
init() {
this.particles = []
// Velocidad menor en móvil para que no se vean tan rápidas
const isMobile = this.canvas.width < 768
const speed = isMobile ? 0.15 : 0.4
const count = Math.floor((this.canvas.width * this.canvas.height) / 12000)
for (let i = 0; i < Math.min(count, 50); i++) {
this.particles.push({
x: Math.random() * this.canvas.width,
y: Math.random() * this.canvas.height,
vx: (Math.random() - 0.5) * speed,
vy: (Math.random() - 0.5) * speed,
radius: 2 + Math.random() * 2,
opacity: 0.25 + Math.random() * 0.25
})
}
this.animate()
}
animate() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
// Mover y dibujar partículas
this.particles.forEach(p => {
p.x += p.vx
p.y += p.vy
if (p.x < 0 || p.x > this.canvas.width) p.vx *= -1
if (p.y < 0 || p.y > this.canvas.height) p.vy *= -1
this.ctx.beginPath()
this.ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2)
this.ctx.fillStyle = `rgba(201, 173, 209, ${p.opacity})`
this.ctx.fill()
})
// Líneas de conexión entre partículas cercanas
const maxDist = 180
for (let i = 0; i < this.particles.length; i++) {
for (let j = i + 1; j < this.particles.length; j++) {
const dx = this.particles[i].x - this.particles[j].x
const dy = this.particles[i].y - this.particles[j].y
const dist = Math.sqrt(dx * dx + dy * dy)
if (dist < maxDist) {
const opacity = (1 - dist / maxDist) * 0.25
this.ctx.beginPath()
this.ctx.strokeStyle = `rgba(201, 173, 209, ${opacity})`
this.ctx.lineWidth = 0.8
this.ctx.moveTo(this.particles[i].x, this.particles[i].y)
this.ctx.lineTo(this.particles[j].x, this.particles[j].y)
this.ctx.stroke()
}
}
}
requestAnimationFrame(() => this.animate())
}
}
document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('hero-particles')
if (canvas) new HeroParticles(canvas)
})