效果图:
视频教程:
https://www.youtube.com/watch?v=Yvz_axxWG4Y
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
<title>Canvas粒子特效</title>
</head>
<body>
<canvas></canvas>
<script src="script.js"></script>
</body>
</html>
CSS:
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
}
JavaScript:
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
const particles = []
let hue = 0
class Particle {
constructor(x, y) {
this.x = x
this.y = y
this.size = Math.random() * 10 + 1
this.speedX = Math.random() * 3 - 1.5
this.speedY = Math.random() * 3 - 1.5
this.color = 'hsl(' + hue + ', 100%, 50%)'
}
update() {
this.x += this.speedX
this.y += this.speedY
if (this.size > 0.2) {
this.size -= 0.1
}
this.draw()
}
draw() {
ctx.fillStyle = this.color
ctx.beginPath()
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2)
ctx.fill()
}
}
window.addEventListener('resize', () => {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
})
window.addEventListener('click', (event) => {
for (let i = 0; i < 10; ++i) {
particles.push(new Particle(event.x, event.y))
}
})
window.addEventListener('mousemove', (event) => {
for (let i = 0; i < 2; ++i) {
particles.push(new Particle(event.x, event.y))
}
})
function handleParticles() {
for (let i = 0; i < particles.length; ++i) {
const p1 = particles[i]
p1.update()
if (p1.size < 0.2) {
particles.splice(i, 1)
i--
} else {
for (let j = i + 1; j < particles.length; ++j) {
const p2 = particles[j]
const dx = p1.x - p2.x
const dy = p1.y - p2.y
const distance = Math.sqrt(dx * dx + dy * dy)
if (distance < 100) {
ctx.strokeStyle = p1.color
ctx.lineWidth = 1
ctx.beginPath()
ctx.moveTo(p1.x, p1.y)
ctx.lineTo(p2.x, p2.y)
ctx.stroke()
ctx.closePath()
}
}
}
}
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
handleParticles()
hue += 1
requestAnimationFrame(animate)
}
animate()