
tsParticles 粒子碰撞交互particles.collisions 选项、三种碰撞模式与检测算法全解【免费下载链接】tsparticlestsParticles - Easily create highly customizable JavaScript particles effects, confetti explosions and fireworks animations and use them as animated backgrounds for your website. Ready to use components available for React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Solid, Riot and Web Components.项目地址: https://gitcode.com/GitHub_Trending/ts/tsparticles本文基于tsparticles/interaction-particles-collisions包的官方 README 及其源码系统讲解 tsParticles 中“粒子与粒子之间”的碰撞交互如何安装并以正确的顺序注册插件、particles.collisions各选项的默认值与完整 JSON 配置、bounce/absorb/destroy 三种碰撞模式的具体物理行为以及碰撞检测与防重叠overlap插件在源码层面的实现细节。读完本文你可以直接在自己的项目中启用粒子碰撞效果并理解碰撞判定、能量修正与粒子吞噬的底层逻辑。插件定位这是“粒子间”交互不是“鼠标”交互先明确这个包的职责边界。根据 包 READMEtsparticles/interaction-particles-collisions是 tsParticles 的 interaction 插件负责particles粒子之间的 collisions碰撞效果。package.json 中它的peerDependencies明确要求同时存在tsparticles/engine与tsparticles/plugin-interactivity两个包peerDependencies: { tsparticles/engine: workspace:*, tsparticles/plugin-interactivity: workspace:* }这一点在 README 的 “Quick checklist” 中也得到了印证——三步走安装tsparticles/engine或使用 CDN 打包文件在调用tsParticles.load(...)之前调用本包的 loader 函数在tsParticles.load(...)的options中应用本包的选项。从源码结构看之所以必须依赖tsparticles/plugin-interactivity是因为碰撞交互器继承自 interaction 体系的基类且加载时会显式校验该插件已就位详见下文 src/index.ts 的解析。三种接入方式CDN/Vanilla、ESM、CommonJSCDN / Vanilla JS / jQuery按 README 说明CDN/Vanilla 形态下只需要引入tsparticles.interaction.particles.collisions.min.js这一个文件它会导出加载函数loadParticlesCollisionsInteraction。初始化与加载插件脚本就绪后README 给出的标准用法是核心在于两个await的顺序(async () { await loadInteractivityPlugin(tsParticles); await loadParticlesCollisionsInteraction(tsParticles); await tsParticles.load({ id: tsparticles, options: {/* options */}, }); })();ESM / CommonJS模块环境下先安装依赖$ npm install tsparticles/interaction-particles-collisions或$ yarn add tsparticles/interaction-particles-collisions然后按模块体系引入。CommonJS 写法const { tsParticles } require(tsparticles/engine); const { loadInteractivityPlugin } require(tsparticles/plugin-interactivity); const { loadParticlesCollisionsInteraction } require(tsparticles/interaction-particles-collisions); (async () { await loadInteractivityPlugin(tsParticles); await loadParticlesCollisionsInteraction(tsParticles); })();ESM 写法import { tsParticles } from tsparticles/engine; import { loadInteractivityPlugin } from tsparticles/plugin-interactivity; import { loadParticlesCollisionsInteraction } from tsparticles/interaction-particles-collisions; (async () { await loadInteractivityPlugin(tsParticles); await loadParticlesCollisionsInteraction(tsParticles); })();从 package.json 的exports字段可以确认该包同时提供了四个产物入口browser、importESM、requireCJS和types并额外导出了一个./lazy子路径对应dist/esm/index.lazy.js等用于按需动态加载场景。源码解析loadParticlesCollisionsInteraction 到底注册了什么src/index.ts 中的加载函数做了三件关键事情export async function loadParticlesCollisionsInteraction(engine: Engine): Promisevoid { engine.checkVersion(__VERSION__); await engine.pluginManager.register((e: InteractivityEngine) { ensureInteractivityPluginLoaded(e); e.pluginManager.addPlugin(new OverlapPlugin()); e.pluginManager.addInteractor?.(particlesCollisions, container { return Promise.resolve(new Collider(container)); }); }); }engine.checkVersion(__VERSION__)校验插件与引擎的版本兼容性这也是各插件统一的前置动作ensureInteractivityPluginLoaded(e)强制要求 interactivity 插件已加载——这正是tsparticles/plugin-interactivity成为 peerDependency 的原因解释了 README 中“Common pitfalls”第一条“在loadInteractivityPlugin(...)之前调用tsParticles.load(...)”会出问题的底层机制注册两样东西new OverlapPlugin()一个容器级插件负责“防止新粒子生成在已有粒子上”详见下文“防重叠”一节名为particlesCollisions的 interactor 工厂每次需要碰撞交互时为当前container创建一个Collider实例。而 src/index.lazy.ts 是同一逻辑的懒加载版本对plugin-interactivity/lazy与OverlapPlugin.js使用Promise.all动态import对Collider.js也延迟到 interactor 工厂被调用时才加载。对应到包入口就是前面提到的./lazy导出路径适合在意首屏体积、希望按需加载碰撞逻辑的项目。选项全景particles.collisions 的完整配置README 给出的最小选项映射是主键particles.collisions{ particles: { collisions: { enable: true } } }结合 Options/Classes/Collisions.ts 中的选项类collisions组的完整字段与默认值如下{ particles: { collisions: { enable: false, mode: bounce, maxSpeed: 50, absorb: { speed: 2 }, bounce: { enable: true }, overlap: { enable: true, retries: 0 } } } }各字段含义依据 Collisions.ts 的字段注释与 CollisionMode.ts 枚举字段类型 / 取值默认值说明enablebooleanfalse是否启用碰撞。默认关闭必须显式设为truemodebounce \| absorb \| destroybounce碰撞发生后的处理方式决定ResolveCollision分派到哪个处理函数maxSpeednumber支持范围值RangeValue50碰撞后粒子的最大速度上限bounce 模式下用于限速absorb.speednumber2absorb 模式下大粒子“吞噬”小粒子的速率bounce对象引擎ParticlesBounce选项组复用引擎内通用的粒子弹跳选项组用于 bounce 模式overlap.enablebooleantrue是否允许粒子相互重叠true表示不做防重叠overlap.retriesnumber0关闭防重叠时放置粒子的重试次数上限两点值得注意collisions是粒子级选项组挂在particles下即作用在粒子选项上。从 Collider.ts 中p1.options.collisions?.enable的判定方式可以推断每个粒子读取的是自己身上的 collisions 配置因此不同粒子群可以有不同的碰撞策略load()方法通过loadProperty/loadRangeProperty逐个字段解析其中maxSpeed走loadRangeProperty说明它支持[min, max]范围写法运行时为每个粒子解析出具体值Bounce.ts 中的getRangeValue(p.options.collisions.maxSpeed)即其消费点。碰撞检测Collider 的判定流程真正执行碰撞检测的是 Collider.ts 的interact()方法。它对每个粒子p1依次做如下过滤任何一条不满足就跳过该候选粒子p2生命周期过滤p1.destroyed || p1.spawning时直接返回——正在销毁或尚未生成完毕的粒子不参与碰撞空间索引加速container.particles.grid.queryCircle(pos1, radius1 * double)用空间网格以2 倍 p1 半径为查询圆圈取候选粒子避免 O(n²) 全量两两比较去重p1.id p2.id时跳过保证每对粒子只被处理一次利用 id 顺序做“每对一次”的去重双方开关p1与p2各自的options.collisions.enable必须都为true模式一致p1.options.collisions.mode ! p2.options.collisions.mode时跳过——即不同碰撞模式的粒子之间互不作用例如一个bounce群和一个absorb群即使重叠也不会互相影响深度z 轴过滤Math.abs(Math.round(pos1.z) - Math.round(pos2.z)) radius1 radius2时跳过。tsParticles 的粒子可带有z坐标模拟纵深深度差超过两者半径之和时视为“不在同一层”不发生碰撞距离判定getDistance(pos1, pos2) radius1 radius2时跳过。只有两圆心距离不超过半径之和即圆形相交才真正触发碰撞。通过全部过滤后调用resolveCollision(p1, p2, delta, container.retina.pixelRatio)进入模式处理。isEnabled 方法则以particle.options.collisions?.enable作为交互器是否对该粒子生效的开关。另外Collider的loadParticlesOptions方法Collider.ts负责把Collisions选项类合并进粒子选项——这是particles.collisions配置最终落到每个粒子身上的通道。三种碰撞模式的实现细节ResolveCollision.ts 根据p1.options.collisions.mode分派到三个处理函数与 CollisionMode.ts 中absorb / bounce / destroy三个枚举值一一对应。mode: bounce默认——带能量修正的弹性碰撞Bounce.ts 的实现分四步记录碰撞前两粒子的质量与速度计算总动能keBefore调用引擎的circleBounce由circleBounceDataFromParticle构造输入执行标准的二维圆碰撞速度交换能量守恒修正若碰撞后总动能keAfter仍大于keBefore * 1e-6计算correctionFactor sqrt(keBefore / keAfter)当该因子偏离 1 超过1e-4阈值时将双方速度同步乘以该因子——这一步保证数值计算不会“凭空造出能量”避免粒子越撞越快限速fixBounceSpeed会把速度长度钳制在collisions.maxSpeed默认 50之内这就是该选项的作用点。mode: absorb——大粒子吞噬小粒子Absorb.ts 中若只有一方有半径另一方为 0半径为 0 的一方直接destroy()双方都有半径时较大的粒子作为吸收方每帧从碰撞 delta 时间计算shrinkAmount clamp(absorbSpeed * delta.factor, 0, r2)absorbSpeed即absorb.speed默认 2吸收方半径按勾股关系增长sqrt(r1² shrinkAmount²)被吸收方半径等量缩小被吸收方size.value缩小到pixelRatio以下时清零并销毁。也就是说absorb 模式呈现“大球吃小球”的视觉效果吞噬速率由absorb.speed控制。mode: destroy——碰撞即消亡较小者消失Destroy.ts 的逻辑若双方都非unbreakable不可摧毁先执行一次bounce弹开对方随后比较半径半径为 0 的一方销毁双方都有半径时销毁半径较小的那个p1.getRadius() p2.getRadius() ? p2 : p1。防重叠OverlapPlugin 保证新粒子不“压”在旧粒子上除碰撞本身外本包还注册了overlap插件。OverlapPlugin.ts 将插件 id 声明为overlap其运行时逻辑在 OverlapPluginInstance.ts 的checkParticlePosition中若粒子的collisions.enable未开启或overlap.enable为true默认值即“允许重叠”直接放行只有当overlap.enable被设为false显式禁止重叠时才会遍历现有粒子检查新位置是否落在任何现有粒子的半径和之内getDistance(pos, p.position) particle.getRadius() p.getRadius()overlap.retries默认 0控制放置重试次数上限超出后抛出Particle is overlapping and cant be placed错误。需要注意命名上的“反向直觉”overlap.enable的默认true表示允许粒子生成时重叠想要“禁止新粒子出现在已有粒子上”必须把它显式设为false并可配合retries提高放置成功率。常见坑与排错建议Common pitfallsREADME 明确列出三条实战注意事项结合源码可以给出更具体的排查方法在loadInteractivityPlugin(...)之前调用了tsParticles.load(...)src/index.ts中的ensureInteractivityPluginLoaded(e)会在插件注册阶段校验 interactivity 插件已加载顺序颠倒会直接导致交互器无法生效。正确顺序永远是先loadInteractivityPlugin(tsParticles)再loadParticlesCollisionsInteraction(tsParticles)最后tsParticles.load(...)启用高级选项前核对所需的 peer 包本包同时依赖tsparticles/engine与tsparticles/plugin-interactivity见 package.json 的peerDependencies缺少其一都会使插件无法注册每次只改一个选项组来隔离回归例如排查 bounce 行为时只动maxSpeed/bounce排查放置重叠时只动overlap避免多变量同时变化导致难以定位。此外基于检测逻辑还有两个易踩的点不同mode的粒子互不碰撞模式必须一致z深度差大于两半径之和的粒子视为不同层不会发生碰撞。小结与延伸阅读tsparticles/interaction-particles-collisions通过一个 interactorCollider 一个容器插件OverlapPlugin的组合实现了粒子间的碰撞检测与三种响应模式并借助空间网格查询保证性能。关键源码入口如下可继续深入README 与快速上手、package.json插件注册src/index.ts、src/index.lazy.ts碰撞检测src/Collider.ts、src/ResolveCollision.ts模式实现src/Bounce.ts、src/Absorb.ts、src/Destroy.ts选项定义src/Options/Classes/Collisions.ts、src/Options/Classes/CollisionsAbsorb.ts、src/Options/Classes/CollisionsOverlap.ts防重叠src/OverlapPlugin.ts、src/OverlapPluginInstance.ts【免费下载链接】tsparticlestsParticles - Easily create highly customizable JavaScript particles effects, confetti explosions and fireworks animations and use them as animated backgrounds for your website. Ready to use components available for React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Solid, Riot and Web Components.项目地址: https://gitcode.com/GitHub_Trending/ts/tsparticles创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考