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

简单效果图

许多读者一开始看到这个效果便望而生畏,其实想要实现上面的效果非常简单,接下来我会带着大家使用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²) → 分片遍历)

三、关键技术亮点

  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);
    });
});
相关推荐
WKK_2 分钟前
uniapp自定义封装tabbar
前端·javascript·小程序·uni-app
莫问alicia3 分钟前
react 常用钩子 hooks 总结
前端·javascript·react.js
Mintopia11 分钟前
图形学中的数学基础与 JavaScript 实践
前端·javascript·计算机图形学
Mintopia18 分钟前
Three.js 制作飘摇的草:从基础到进阶的全流程教学
前端·javascript·three.js
BillKu18 分钟前
Vue3父子组件数据双向同步实现方法
前端·javascript·vue.js
红尘散仙38 分钟前
七、WebGPU 基础入门——Texture 纹理
前端·rust·gpu
jaywongX39 分钟前
Base64编码原理:二进制数据与文本的转换技术
前端·javascript·vue
红尘散仙39 分钟前
八、WebGPU 基础入门——加载图像纹理
前端·rust·gpu
佳腾_42 分钟前
【Web应用服务器_Tomcat】一、Tomcat基础与核心功能详解
java·前端·中间件·tomcat·web应用服务器
天天扭码1 小时前
深入讲解Javascript中的常用数组操作函数
前端·javascript·面试