2分钟创建一个“不依赖任何外部库”的粒子动画背景

本篇依然来自于我们的 《前端周刊》 项目!

由团队成员 掘金安东尼 翻译,也就是本瓜咯,欢迎大家 进群 持续追踪全球最新前端资讯!!

原文:particle-background-effect-with-canvas

我一直想做一个轻量的、细腻的动画背景效果,不依赖任何外部库。 这个 React 组件完全使用 HTML5 Canvas API 来渲染一个带有动画连线的粒子系统,既轻量、可定制,又容易集成到任何现代 UI 中。

在进入代码之前,先看看它的运行效果。你也可以访问我的个人网站 stevejonk.com 在浏览器中查看。

组件结构

效果的核心是一个 React 组件 Background.tsx ,它会在 <canvas> 上绘制并动画化粒子。 每个粒子独立移动,当两个粒子彼此靠近时,会绘制一条连接它们的线。

主要特性:

  • 自适应:Canvas 会随窗口大小调整。
  • 可定制:粒子数量、速度、颜色、连线半径等参数都可以轻松修改。
  • 高效 :使用 requestAnimationFrame 实现流畅动画。

工作原理

  • 粒子:每个粒子有位置、速度、方向和颜色,它们会在 Canvas 边缘反弹。
  • 连线:当两个粒子之间的距离小于指定阈值时,会绘制一条线,透明度与距离成反比。
  • 动画循环 :组件通过 requestAnimationFrame 更新并重绘画面。

代码解析

Canvas 初始化

使用 ref 获取 Canvas 元素,并将其尺寸设为窗口大小,同时在窗口调整时重置:

Plain 复制代码
const resizeReset = () => { w = canvas.width = window.innerWidth h = canvas.height = window.innerHeight } window.addEventListener('resize', resizeReset)

粒子类

每个粒子由一个类表示,包含位置、速度、方向和颜色。update 方法负责移动粒子并在触碰边界时反弹:

kotlin 复制代码
Plain Text class Particle { update() { this.border() this.x += this.vector.x this.y += this.vector.y } border() { if (this.x >= w || this.x <= 0) this.vector.x *= -1 if (this.y >= h || this.y <= 0) this.vector.y *= -1 if (this.x >= w) this.x = w if (this.y >= h) this.y = h if (this.x < 0) this.x = 0 if (this.y < 0) this.y = 0 } }

初始化粒子

粒子会被随机赋予位置和速度,数量与连线半径会根据窗口大小动态调整:

scss 复制代码
Plain Text const initializeParticles = () => { options.particleAmount = (w + h) / 50 options.linkRadius = w / 10 + h / 5 particles = [] for (let i = 0; i < options.particleAmount; i++) { particles.push(new Particle()) } }

绘制与动画

每一帧会先清除 Canvas,再更新并绘制粒子,同时绘制相邻粒子间的连线:

scss 复制代码
Plain Text const drawParticles = () => { particles.forEach((p) => { p.update() p.draw() }) }

const linkPoints = (point, hubs) => { hubs.forEach((hub) => { const distance = checkDistance(point.x, point.y, hub.x, hub.y) const opacity = 1 - distance / options.linkRadius if (opacity > 0) { ctx.strokeStyle = `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${opacity})` ctx.beginPath() ctx.moveTo(point.x, point.y) ctx.lineTo(hub.x, hub.y) ctx.stroke() } }) }

const loop = () => { ctx.clearRect(0, 0, w, h) drawLines() drawParticles() loopId = requestAnimationFrame(loop) }

源码

完整代码可在本仓库的 components/Background.tsx 中查看。

这个效果是一种无需引入庞大依赖,就能为网站背景增添现代感与交互性的好方法。

html版本

codepen.io

css 复制代码
Plain Text Particle Background --- Vanilla Canvas

**Particles** + 多 - 少 暂停/继续

译者点评

这种完全不依赖第三方库、直接基于 HTML5 Canvas API 的粒子背景实现,非常轻量,且易于集成到任意项目中。

作为一次动手实践,这类效果既能训练你对 Canvas 绘图与动画的掌握,也能帮助理解动画性能优化与响应式适配的思路,是前端开发者日常积累中很值得尝试的一个小项目。

相关推荐
wdfk_prog26 分钟前
嵌入式面试真题第 10 题:高优化等级下共享状态可见性、内存模型与系统级同步设计
java·linux·开发语言·面试·职场和发展·架构·c
谭光志2 小时前
Vibe Coding 时代,程序员该何去何从
前端·后端·ai编程
胡萝卜术2 小时前
RAG 的知识炼油厂:从原始网页到可检索知识块的工程化之路
面试·架构·github
wdfk_prog2 小时前
嵌入式面试真题第 11 题:RTOS 优先级翻转与实时任务阻塞的通用治理
c语言·缓存·面试·职场和发展·架构
仿生狮子4 小时前
别再说“全栈”了,AI 时代团队只认这 5 种人
前端·人工智能·后端
kyriewen4 小时前
AI 写的 React 组件,合并前必查的 6 个坏味道——每个都有代码对比
前端·javascript·react.js
Highcharts.js4 小时前
软件开发公司为什么选择 Highcharts?
前端·前端框架·echarts·数据可视化·技术选型·highcharts·图表工具
阿祖zu4 小时前
企业 AI 转型之痛,个人提效十倍不止,组织效率仍止步不前?
前端·aigc·agent
摇滚侠6 小时前
SpringBoot3+Vue3 全套视频教程 45-51
前端·javascript·vue.js
酸梅果茶6 小时前
【6】lightning_lm项目-LIO 前端 -点云预处理模块
前端·slam