
“Light fireworks with your hands” — Gesture Fireworks ✨
Project Repository
Repository: Gesture Fireworks (a MediaPipe-based interactive gesture fireworks toy) (GitHub)
1. What Is This Little Project Trying to Solve?
Every New Year’s Eve, Spring Festival, and fireworks festival, we always end up scrolling past all kinds of fireworks videos — but they are either too loud, not eco-friendly, or… too hard on the wallet 😅
So I built a lightweight and fun experimental project: Gesture Fireworks. Its core goal is — to let you “set off fireworks” in the air with gestures, using nothing but a computer with a camera + a browser.
Make a ✊, ✌️, or heart ❤️ gesture at the camera, and the corresponding firework effect blooms right by your hand on screen. No client to install, no complicated hardware — open the web page, grant camera access, and you can play.
2. Project Features at a Glance: What Can It Actually Do?
In the current version, Gesture Fireworks implements these capabilities:
-
AI gesture recognition: a MediaPipe-based gesture recognition approach that supports a variety of different gestures
-
Gorgeous firework effects: several kinds of fireworks, carefully designed, including:
- Burst firework (FireworkBurst)
- Ring firework (FireworkCircle)
- Heart-shaped firework (FireworkHeart)
- Star-shaped firework (FireworkStar)
- Spiral firework (FireworkSpiral)
- Umbrella-shaped firework (FireworkUmbrella)
- and more
-
Multiple hands triggering at the same time: both hands can make different gestures simultaneously, each triggering its own fireworks, with an independent cooldown mechanism
-
High-performance rendering: an optimized Canvas 2D particle system that renders thousands of particles at once while staying smooth
-
Smart recognition algorithm: multi-frame smoothing, stable-frame detection, dynamic thresholds, and a cooldown mechanism to minimize misdetection jitter
-
Responsive page: compatible with both desktop & mobile
3. The “Binding Relationship” Between Gestures and Fireworks
To make the experience more intuitive, I designed a different firework style for each common gesture:
| Gesture | Recognized name | Corresponding firework | Visual style |
|---|---|---|---|
| ✊ Fist | FIST | FireworkBurst | Golden, multi-layered circular burst; strong sense of impact |
| 👌 OK gesture | OK | FireworkCircle | Red-orange double-ring, high-density burst |
| ❤️ Finger heart | HEART | FireworkHeart | Pink heart-shaped firework; atmosphere turned all the way up |
| 👍 Thumbs up | THUMBS_UP | FireworkStar | Gold-white five-pointed star burst; prominent flicker |
| ✌️ Peace sign | PEACE | FireworkSpiral | Purple spiral spreading out with a rotating trail |
| 👉 Pointing | POINTING | FireworkUmbrella | Blue umbrella-shaped firework with soft trailing |
| ✋ Open palm | OPEN_PALM | FireworkA | Random-color ring burst + trail; the basic, all-purpose one |
Technically, in the entry logic, the recognized gesture type is mapped to a different trigger function, with different parameters passed in (particle count, color scheme, duration, etc.), so that every gesture has a clearly distinct feel and visual feedback.
4. Gesture Recognition: How to Make Recognition as “Accurate” as Possible
Building a demo that can merely “recognize” gestures is simple, but to make it “fun and not annoying”, you must keep the misdetection rate and jitter under control. To that end, I added several layers of processing logic:
1. Multi-frame Smoothing + Stable-frame Determination
- Use a fixed-length history of frames (e.g.
smoothingFrames = 10) for smoothing - Only when several consecutive frames (e.g.
stableFrames = 6) are all stably recognized as the same gesture is it treated as “truly recognized”
This filters out brief jitter or transition frames and makes triggering more controllable.
2. Dynamic Confidence Thresholds
Different gestures are not equally prone to confusion, so I adopted a threshold design with better discriminability:
- For easily confused gestures (fist, OK, thumbs up, peace sign, pointing, etc.), the threshold is set to
0.85 - For open palm (OPEN_PALM), the threshold is slightly lower, at
0.8
At the same time, the difference in confidence between the first- and second-ranked gestures must be ≥ 0.12, so that two “evenly matched” gestures do not jump around.
3. Cooldown Mechanism + Rising-edge Triggering
- Each recognizer has a default cooldown of
cooldownMs = 350ms - A firework is triggered only when “the stable gesture changes from A to B” and it is not within the cooldown period
This means you can hold one gesture still and the fireworks will not fire endlessly; it feels more like “one clear action → one clear piece of feedback”.
5. Rendering Layer: Design Approach for the Canvas Particle System
The visual part implements a lightweight particle system on Canvas 2D:
-
Each firework is essentially a collection of a large number of particles (position, velocity, acceleration, color, opacity, and other attributes)
-
Each frame does the following:
- Update particle positions (gravity, damping, initial velocity direction, etc.)
- Decay opacity & size
- Compose glow, trailing, flicker, and other effects
To guarantee performance, I did a few things:
- Batch updates & drawing to reduce redundant state switches
- For each firework type, cap the maximum particle count to avoid blowing up memory
- When many fireworks are active, clean up particles that are already “invisible” first
On an ordinary laptop with a modern browser, thousands of particles can exist at the same time while keeping a fairly smooth experience.
6. Project Structure & Tech Stack Overview
Overall, the project is a very standard little front-end app:
-
Tech stack
- Mostly JavaScript (about 97.7%)
- A little HTML structure
- MediaPipe hand gesture detection (included via a vendor dependency)
-
Main directories
-
src/hand: gesture recognition and higher-level logic (confidence, stability, cooldown, etc.) -
src/main.js: main application entry, responsible for:- Camera capture and video stream
- Calling the recognition module
- Triggering different fireworks based on gesture
-
src/fireworks/*: implementations of the different firework effects
-
The goal is simply: keep the structure clear, and make it easy to add new gestures & new firework types later.
7. How to Run It Locally
As long as you know a little about front-end development, you can get it running quickly.
1. Environment Setup
- A modern browser (Chrome 88+, Firefox 85+, Safari 14+, Edge 88+)
- A device with a camera
- A local HTTP server (used to obtain camera permission)
- A network connection (to load the MediaPipe model the first time)
2. Startup Steps (Example)
# 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
Then visit the following in your browser:
http://localhost:8000
The browser will pop up a camera authorization request; click “Allow” to start playing.
8. Hands-on Experience: How to Play It Better
Drawing on the debugging process, I summarized some practical tips:
-
Good lighting: front lighting is best; avoid backlight and strong shadows
-
Right distance: keep 1–2 meters between yourself and the camera, and the effect is best when your hand occupies about 1/4 of the frame
-
Clear, steady gestures:
- Hold the gesture for 1–2 seconds after making it
- Fingers should be fully extended / sufficiently curled; avoid half-hearted poses
-
Stay more central: keep your hand in the central area of the frame as much as possible; the edges are prone to distortion and inaccurate recognition
-
Multi-hand play: make a different gesture with each hand to light up “combo fireworks”, which makes it very well suited to playing with several people together
If you are interested in this project, you are welcome to visit the repository to look at the source code, file an Issue, or play along