简单效果图
许多读者一开始看到这个效果便望而生畏,其实想要实现上面的效果非常简单,接下来我会带着大家使用canvas,一步一步实现各种效果
一、技术实现原理
本案例通过 HTML5 Canvas 结合动态算法,实现具有以下特性的粒子系统:
-
动态粒子运动:每个粒子具备随机速度与边界反弹机制
-
智能连线交互:自动检测邻近粒子并绘制渐变透明连线
-
响应式布局:窗口尺寸变化时自动重置画布和粒子分布 [2][4]
二、代码结构解析
1. HTML 基础框架
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
canvas {
position: fixed;
left: 0;
top: 0;
background: #222;
}
</style>
</head>
<body>
<canvas></canvas>
<script src="./index.js"></script>
</body>
</html>
-
<meta name="viewport">
确保移动端显示适配 -
Canvas 通过 CSS 实现全屏固定定位
-
外部 JS 文件分离实现模块化开发
2. 核心 JS 模块
(1) 初始化模块
js
const cvs = document.querySelector('canvas');
ctx = cvs.getContext('2d');
function init() {
cvs.width = window.innerWidth;
cvs.height = window.innerHeight;
}
-
getContext('2d')
获取 2D 渲染上下文 -
动态设置画布尺寸适配屏幕分辨率
(2) 粒子类 (Point)
js
class Point {
constructor() {
this.r = 6; // 粒子半径
this.x = getRandom(this.r, cvs.width - this.r); // X轴随机位置
this.y = getRandom(this.r, cvs.height - this.r); // Y轴随机位置
this.vx = getRandom(-0.5, 0.5); // X轴速度
this.vy = getRandom(-0.5, 0.5); // Y轴速度
}
update() {
// 边界反弹检测
if (this.x < this.r || this.x > cvs.width - this.r) this.vx *= -1;
if (this.y < this.r || this.y > cvs.height - this.r) this.vy *= -1;
this.x += this.vx;
this.y += this.vy;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.fillStyle = '#fff';
ctx.fill();
}
}
-
粒子对象封装运动轨迹与绘制方法
-
速度取反实现边界反弹效果
(3) 图形控制器 (Graph)
js
class Graph {
constructor() {
this.points = new Array(100).fill(0).map(() => new Point());
this.maxDis = 200; // 最大连线距离
this.animate();
}
animate() {
ctx.clearRect(0, 0, cvs.width, cvs.height);
this.points.forEach(p => p.update());
this.draw();
requestAnimationFrame(() => this.animate());
}
draw() {
this.points.forEach((p1, i) => {
p1.draw();
this.points.slice(i + 1).forEach(p2 => {
const d = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
if (d > this.maxDis) return;
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.strokeStyle = `rgba(255, 255, 255, ${1 - d / this.maxDis})`;
ctx.stroke();
});
});
}
}
-
requestAnimationFrame
实现 60FPS 流畅动画 -
距离检测算法优化性能(O (n²) → 分片遍历)
三、关键技术亮点
-
运动轨迹优化
- 速度随机值范围控制在 [-0.5, 0.5]
- 距离检测公式:
Math.sqrt(Δx² + Δy²)
-
视觉效果增强
- 连线透明度与距离成反比:
1 - d/maxDis
- 黑色背景与白色粒子形成高对比度
- 连线透明度与距离成反比:
-
响应式处理
- 窗口尺寸变化时重新初始化粒子位置
js
window.addEventListener('resize', () => {
init();
g.points.forEach(p => {
p.x = getRandom(p.r, cvs.width - p.r);
p.y = getRandom(p.r, cvs.height - p.r);
});
});