Canvas粒子系统终极指南:从基础运动到复杂交互的全流程实现

ops/2025/4/1 3:19:33/

文章目录

  • 一、粒子系统基础架构
    • 1.1 粒子数据结构设计
    • 1.2 粒子系统管理器
  • 二、基础粒子效果实现
    • 2.1 重力场模拟
    • 2.2 弹性碰撞效果
  • 三、高级交互实现
    • 3.1 鼠标吸引效果
    • 3.2 颜色渐变粒子
  • 四、性能优化策略
    • 4.1 粒子池复用
    • 4.2 分层渲染
  • 五、复杂效果实现
    • 5.1 烟花爆炸效果
    • 5.2 流体模拟


一、粒子系统基础架构

1.1 粒子数据结构设计

class Particle {constructor(x, y) {this.pos = { x, y };this.vel = { x: Math.random()*4 - 2, y: Math.random()*4 - 2 };this.acc = { x: 0, y: 0.1 };this.size = Math.random()*8 + 2;this.life = 200;}update() {this.vel.x += this.acc.x;this.vel.y += this.acc.y;this.pos.x += this.vel.x;this.pos.y += this.vel.y;this.life--;}
}

1.2 粒子系统管理器

class ParticleSystem {constructor() {this.particles = [];this.emitRate = 5;this.gravity = 0.1;}emit(x, y) {for(let i=0; i<this.emitRate; i++) {this.particles.push(new Particle(x, y));}}update() {this.particles = this.particles.filter(p => p.life > 0);this.particles.forEach(p => p.update());}
}

二、基础粒子效果实现

2.1 重力场模拟

// 初始化时设置重力
class GravityParticle extends Particle {constructor(x, y) {super(x, y);this.acc.y = 0.3; // 增强重力效果}
}// 鼠标点击触发粒子发射
canvas.addEventListener('click', (e) => {const rect = canvas.getBoundingClientRect();const x = e.clientX - rect.left;const y = e.clientY - rect.top;particleSystem.emit(x, y);
});

2.2 弹性碰撞效果

class BounceParticle extends Particle {update() {super.update();// 水平边界碰撞if(this.pos.x < 0 || this.pos.x > canvas.width) {this.vel.x *= -0.8;this.pos.x = Math.max(0, Math.min(this.pos.x, canvas.width));}// 垂直边界碰撞if(this.pos.y < 0 || this.pos.y > canvas.height) {this.vel.y *= -0.8;this.pos.y = Math.max(0, Math.min(this.pos.y, canvas.height));}}
}

三、高级交互实现

3.1 鼠标吸引效果

class AttractorParticle extends Particle {constructor(x, y) {super(x, y);this.attraction = 0.02;}update(mousePos) {super.update();const dx = mousePos.x - this.pos.x;const dy = mousePos.y - this.pos.y;const distance = Math.sqrt(dx*dx + dy*dy);if(distance < 200) {const force = (200 - distance) * this.attraction;this.vel.x += (dx/distance) * force;this.vel.y += (dy/distance) * force;}}
}

3.2 颜色渐变粒子

class GradientParticle extends Particle {constructor(x, y) {super(x, y);this.colorStart = `hsl(${Math.random()*360}, 80%, 60%)`;this.colorEnd = `hsl(${Math.random()*360}, 80%, 30%)`;}draw(ctx) {const gradient = ctx.createRadialGradient(this.pos.x, this.pos.y, 0, this.pos.x, this.pos.y, this.size);gradient.addColorStop(0, this.colorStart);gradient.addColorStop(1, this.colorEnd);ctx.beginPath();ctx.arc(this.pos.x, this.pos.y, this.size, 0, Math.PI*2);ctx.fillStyle = gradient;ctx.fill();}
}

四、性能优化策略

4.1 粒子池复用

class PooledParticleSystem extends ParticleSystem {constructor() {super();this.pool = [];}emit(x, y) {for(let i=0; i<this.emitRate; i++) {const particle = this.pool.length ? this.pool.pop() : new Particle(x, y);particle.reset(x, y);this.particles.push(particle);}}remove(particle) {this.pool.push(particle);}
}

4.2 分层渲染

function render() {ctx.clearRect(0, 0, canvas.width, canvas.height);// 背景层(透明粒子)backgroundParticles.forEach(p => p.draw(ctx));// 交互层(高亮粒子)interactiveParticles.forEach(p => p.draw(ctx));requestAnimationFrame(render);
}

五、复杂效果实现

5.1 烟花爆炸效果

class FireworkParticle extends Particle {constructor(x, y) {super(x, y);this.vel.y = -Math.random()*6 - 8;this.acc.y = 0.05;this.size = Math.random()*15 + 5;}draw(ctx) {ctx.beginPath();ctx.arc(this.pos.x, this.pos.y, this.size, 0, Math.PI*2);ctx.fillStyle = `hsl(${Math.random()*360}, 80%, 60%)`;ctx.fill();}
}

5.2 流体模拟

class FluidParticle extends Particle {constructor(x, y) {super(x, y);this.density = Math.random()*50 + 10;}update() {super.update();this.vel.x *= 0.95;this.vel.y *= 0.95;}draw(ctx) {ctx.beginPath();ctx.arc(this.pos.x, this.pos.y, this.size, 0, Math.PI*2);ctx.fillStyle = `rgba(0, 255, 255, ${this.density/100})`;ctx.fill();}
}

到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 Vue 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕

在这里插入图片描述


http://www.ppmy.cn/ops/170762.html

相关文章

ADZS-ICE-2000和AD-ICE2000仿真器在线升级固件

作者的话 近期发现有些兄弟的ICE-2000仿真器链接DSP报错&#xff0c;然后test第四步不通过&#xff0c;我就拿我的仿真器也试了一下&#xff0c;发现ADI悄咪咪的在线升级仿真器固件&#xff0c;有些兄弟不会操作&#xff0c;就会导致仿真器升级失败&#xff0c;连不上目标板&a…

RTMP推流+EasyDSS云服务+边缘AI分析的无人机监控系统设计

在现代科技不断发展的背景下&#xff0c;无人机技术已经广泛应用于各个领域&#xff0c;从航拍摄影到工业巡检&#xff0c;从农业监测到应急救援&#xff0c;无人机以其高效的工作能力&#xff0c;为人们的生活和工作带来了诸多便利与创新&#xff0c;而其视频传输与分析系统更…

STL入门

STL入门 作者&#xff1a;blue 时间&#xff1a;2024.3 文章目录 STL入门0.概述1.pair2.set(集合)3.vector4.string字符串类型5.queue&#xff0c;deque&#xff0c;priority_queue6.list的用法 0.概述 本文讨论部分常用的STL的运用 1.pair pair是将2个数据组合成一组数据…

leetcode240.搜索二维矩阵||

从右上角开始&#xff0c;往左移动就是变小&#xff0c;往下移动就是增加&#xff0c;类似于二叉搜索树&#xff0c;当目标大于矩阵只就下移&#xff0c;小于就左移 class Solution {public boolean searchMatrix(int[][] matrix, int target) {int mmatrix.length,nmatrix[0]…

MYTOOL-电路模块

一、前言 目录 1.原型设计 2.程序实现 3.最终界面说明 二、环境 windows10 每个软件工具前期会设计大概的原型&#xff0c;我设计的原型工具使用Axure RP9&#xff0c;很不错的一个设计工具 三、正文 1.原型设计 2.程序实现 3.最终界面说明 四、结语

如何备份你的 Postman 所有 Collection?

团队合作需要、备份&#xff0c;还是迁移到其他平台&#xff0c;我们都需要在 Postman 中将这些珍贵的集合数据导出。 如何从 Postman 中导出所有集合(Collection)教程

VMware 安装 Ubuntu 实战分享

VMware 安装 Ubuntu 实战分享 VMware 是一款强大的虚拟机软件&#xff0c;广泛用于多操作系统环境的搭建。本文将详细介绍如何在 VMware 中安装 Ubuntu&#xff0c;并分享安装过程中的常见问题及解决方法。 1. 安装前的准备工作 (1) 系统要求 主机操作系统&#xff1a;Windo…

工作督导 | 辅导员与心理中心的配合——开学季心理普测棘手问题(人员篇)

一个学校心理中心&#xff0c;可能同时有几十位乃至数百位同学在接受咨询&#xff0c;其中大约10-20%是重点难点个案&#xff0c;一次督导如果只能督导1-2个个案&#xff0c;不足以保障所有危重难个案的有如何处理恰当、方向正确、快速解决、高效工作&#xff0c;是学校心理咨询…