《Canvas 炫酷动态粒子连线:从零打造流动星空特效》

简单效果图

许多读者一开始看到这个效果便望而生畏,其实想要实现上面的效果非常简单,接下来我会带着大家使用canvas,一步一步实现各种效果

一、技术实现原理

本案例通过 HTML5 Canvas 结合动态算法,实现具有以下特性的粒子系统:

  • 动态粒子运动:每个粒子具备随机速度与边界反弹机制

  • 智能连线交互:自动检测邻近粒子并绘制渐变透明连线

  • 响应式布局:窗口尺寸变化时自动重置画布和粒子分布 24

二、代码结构解析

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²) → 分片遍历)

三、关键技术亮点

  1. 运动轨迹优化

    • 速度随机值范围控制在 -0.5, 0.5
    • 距离检测公式:Math.sqrt(Δx² + Δy²)
  2. 视觉效果增强

    • 连线透明度与距离成反比:1 - d/maxDis
    • 黑色背景与白色粒子形成高对比度
  3. 响应式处理

  • 窗口尺寸变化时重新初始化粒子位置
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);
    });
});
相关推荐
铁皮饭盒37 分钟前
Next.js 风格路由内置?Bun FileSystemRouter 凭啥这么香
javascript
乘风gg38 分钟前
多 Agent 不是万能的!搞懂这 5 个原则,少走 1 年弯路!
前端·agent·ai编程
猩猩程序员1 小时前
Vercel 推出 Agent 框架 Eve:让 AI Agent 像写 Web 应用一样简单
前端
小林ixn2 小时前
别再背八股了!从 5 个真实场景彻底搞懂 JavaScript 的 this
javascript
爱读源码的大都督2 小时前
Claude Code源码分析(三):为什么系统提示词中需要有tools呢?
前端·人工智能·后端
爱勇宝2 小时前
Claude Code 被曝暗藏“隐形检测”代码:封代理不是最可怕的,可怕的是你根本不知道它在干什么
前端·后端·程序员
小牛不牛的程序员2 小时前
我用 Claude Code 半天撸完了一个完整网站,AI 编程到底提升了多少效率?
前端
东风破_2 小时前
JavaScript 面试常考的字符串算法:从反转字符串到回文判断
前端·javascript
巴勒个啦2 小时前
D3.js 入门实战:用力导向图可视化项目依赖关系
javascript
ITOM运维行者2 小时前
从零搭建企业级服务器监控体系:踩坑实录与架构设计
前端·后端