Gesture-Fireworks

「用手点燃烟花」——Gesture Fireworks ✨
项目地址
仓库地址:Gesture Fireworks(基于 MediaPipe 的手势烟花互动小工具)(GitHub)
一、这个小项目想解决什么?
每年跨年、春节、烟花节,我们总会刷到各种烟花视频,但要么太吵,要么不环保,要么……钱包受不了 😅
于是我做了一个轻量又好玩的实验项目:Gesture Fireworks(手势烟花)。 它的核心目标是——让你只用一台带摄像头的电脑 + 浏览器,就能用手势在空中「放烟花」。
你对着摄像头比一个 ✊、✌️ 或比心 ❤️,画面中就会在你的手边绽放对应的烟花效果。 不需要安装客户端,不需要复杂硬件,打开网页、授权摄像头,就能玩。
二、项目功能一览:它到底能干嘛?
在目前的版本中,Gesture Fireworks 实现了这几类能力:
AI 手势识别:基于 MediaPipe 的手势识别方案,支持多种不同手势
绚丽烟花特效:精心设计了多种烟花,包括:
- 爆炸烟花(FireworkBurst)
- 圆环烟花(FireworkCircle)
- 心形烟花(FireworkHeart)
- 星形烟花(FireworkStar)
- 螺旋烟花(FireworkSpiral)
- 伞形烟花(FireworkUmbrella)
- 等等
多手同时触发:双手可以同时做不同手势,各自单独触发烟花,带有独立冷却机制
高性能渲染:使用优化过的 Canvas 2D 粒子系统,可以同时渲染数千粒子而保持顺畅
智能识别算法:多帧平滑、稳定帧判定、动态阈值、冷却机制,尽量减少误判抖动
响应式页面:同时兼容桌面端 & 移动端
三、手势和烟花的「绑定关系」
为了让体验更「直觉」,我为常见手势设计了不同的烟花风格:
| 手势 | 识别名 | 对应烟花 | 视觉风格 |
|---|---|---|---|
| ✊ 拳头 | FIST | FireworkBurst | 金黄色多层圆形爆炸,冲击感强 |
| 👌 OK 手势 | OK | FireworkCircle | 红橙系双环高密度爆裂 |
| ❤️ 比心 | HEART | FireworkHeart | 粉色系心形烟花,氛围感拉满 |
| 👍 竖拇指 | THUMBS_UP | FireworkStar | 金白色五角星爆炸,闪烁明显 |
| ✌️ 剪刀手 | PEACE | FireworkSpiral | 紫色螺旋扩散,有旋转轨迹 |
| 👉 指向 | POINTING | FireworkUmbrella | 蓝色伞形烟花,拖尾柔和 |
| ✋ 张开手掌 | OPEN_PALM | FireworkA | 随机色环形爆裂 + 拖尾,基础通用款 |
技术上,在入口逻辑里会根据识别到的手势类型,映射到不同的触发器函数,并传入不同的参数(粒子数量、配色、持续时间等),让每种手势都有明显区别的手感和视觉反馈。
四、手势识别:怎么尽量识别得「准一点」?
单纯做一个「能识别」的 Demo 很简单,但要做到「好玩、不烦人」,就必须控制误识别率和抖动。为此我做了几层处理逻辑:
1. 多帧平滑 + 稳定帧判定
- 使用固定长度的历史帧(例如
smoothingFrames = 10)做平滑 - 只有连续若干帧(例如
stableFrames = 6)都稳定识别为同一手势时,才视为「真正识别到」
这样可以过滤掉短暂的抖动或过渡帧,让触发更可控。
2. 动态置信度阈值
不同手势本身的易混淆程度不一样,所以采用了区分度更高的阈值设计:
- 对于容易混的手势(拳头、OK、点赞、剪刀手、指向等),阈值设为
0.85 - 对于张开手掌(OPEN_PALM),阈值略低一点
0.8
同时,还会要求第一名和第二名手势的置信度差值 ≥ 0.12,避免「半斤八两」的两种手势乱跳。
3. 冷却机制 + 上升沿触发
- 每个识别器有一个默认冷却时间
cooldownMs = 350ms - 只有当「稳定手势从 A 变为 B」且不在冷却期内,才会触发一次烟花
这意味着你可以保持一个手势不动,烟花不会无限制连发,更像是「一次明确的动作 → 一次清晰的反馈」。
五、渲染层:Canvas 粒子系统的设计思路
视觉部分基于 Canvas 2D 实现了一个轻量的粒子系统:
每个烟花本质上是大量粒子(位置、速度、加速度、颜色、透明度等属性)的集合
每一帧进行:
- 粒子位置更新(重力、阻尼、初速度方向等)
- 透明度 & 尺寸衰减
- 组合出光晕、拖尾、闪烁等效果
为了保证性能,我做了几件事:
- 批量更新 & 绘制,减少多余的状态切换
- 针对不同烟花类型,限制最大粒子数量,避免堆爆内存
- 在多发烟花场景下优先清理已经「看不见」的粒子
在普通笔记本 + 现代浏览器环境下,同时存在数千个粒子仍可以保持比较流畅的体验。
六、项目结构 & 技术栈简述
项目整体是一个很标准的前端小应用形态:
技术栈
- JavaScript 为主(约 97.7%)
- 少量 HTML 结构
- MediaPipe 手势检测(通过 vendor 依赖引入)
主要目录
src/hand:手势识别与高级逻辑(置信度、稳定性、冷却等)src/main.js:应用主入口,负责:- 摄像头采集与视频流
- 调用识别模块
- 根据手势触发不同烟花
src/fireworks/*:不同烟花特效的实现
目的就是:保持结构清晰,方便以后扩展新的手势 & 新的烟花类型。
七、如何本地跑起来?
只要你对前端略有了解,就可以很快跑起来。
1. 环境准备
- 现代浏览器(Chrome 88+、Firefox 85+、Safari 14+、Edge 88+)
- 一台带摄像头的设备
- 本地 HTTP 服务器(用于获取摄像头权限)
- 网络连接(首次加载 MediaPipe 模型)
2. 启动步骤(示例)
# 1. 克隆项目
git clone https://github.com/your-username/Gesture-fireworks.git
cd Gesture-fireworks
# 2. 启动本地服务器(Python 3 示例)
python -m http.server 8000
# 或者使用 Node.js
npx http-server -p 8000 -a localhost然后在浏览器中访问:
http://localhost:8000
浏览器会弹出摄像头授权请求,点击「允许」即可开始体验。
八、实际体验:怎么玩得更爽?
结合调试过程,总结了一些实用的小技巧:
光线充足:正面光最好,避免背光和强阴影
距离合适:人与摄像头保持 1–2 米,手部占画面约 1/4 效果最佳
手势清晰稳定:
- 比完手势后保持 1–2 秒
- 手指要伸直 / 收紧到位,避免半吊子动作
居中一点:手尽量在画面中央区域,边缘区域容易畸变、识别不准
多手玩法:双手分别做不同手势,可以点亮「组合烟花」,非常适合多人一起玩
如果你对这个项目有兴趣,欢迎来仓库看看源码、提 Issue 或一起玩