← 返回文章列表

Gesture-Fireworks

結合手勢識別與前端視覺效果,讓螢幕上的煙花跟隨手指。

daily

「用手點燃煙花」——Gesture Fireworks ✨

專案地址

倉庫地址:Gesture Fireworks(基於 MediaPipe 的手勢煙花互動小工具)(GitHub)


一、這個小專案想解決什麼?

每年跨年、春節、煙花節,我們總會刷到各種煙花影片,但要麼太吵,要麼不環保,要麼……錢包受不了 😅

於是我做了一個輕量又好玩的實驗專案:Gesture Fireworks(手勢煙花)。 它的核心目標是——讓你只用一臺帶攝像頭的電腦 + 瀏覽器,就能用手勢在空中「放煙花」。

你對著攝像頭比一個 ✊、✌️ 或比心 ❤️,畫面中就會在你的手邊綻放對應的煙花效果。 不需要安裝客戶端,不需要複雜硬體,開啟網頁、授權攝像頭,就能玩。


二、專案功能一覽:它到底能幹嘛?

在目前的版本中,Gesture Fireworks 實現了這幾類能力:

  • AI 手勢識別:基於 MediaPipe 的手勢識別方案,支援多種不同手勢

  • 絢麗煙花特效:精心設計了多種煙花,包括:

    • 爆炸煙花(FireworkBurst)
    • 圓環煙花(FireworkCircle)
    • 心形煙花(FireworkHeart)
    • 星形煙花(FireworkStar)
    • 螺旋煙花(FireworkSpiral)
    • 傘形煙花(FireworkUmbrella)
    • 等等
  • 多手同時觸發:雙手可以同時做不同手勢,各自單獨觸發煙花,帶有獨立冷卻機制

  • 高效能渲染:使用最佳化過的 Canvas 2D 粒子系統,可以同時渲染數千粒子而保持順暢

  • 智慧識別演算法:多幀平滑、穩定幀判定、動態閾值、冷卻機制,儘量減少誤判抖動

  • 響應式頁面:同時相容桌面端 & 移動端


三、手勢和煙花的「繫結關係」

為了讓體驗更「直覺」,我為常見手勢設計了不同的煙花風格:

手勢識別名對應煙花視覺風格
✊ 拳頭FISTFireworkBurst金黃色多層圓形爆炸,衝擊感強
👌 OK 手勢OKFireworkCircle紅橙系雙環高密度爆裂
❤️ 比心HEARTFireworkHeart粉色系心形煙花,氛圍感拉滿
👍 豎拇指THUMBS_UPFireworkStar金白色五角星爆炸,閃爍明顯
✌️ 剪刀手PEACEFireworkSpiral紫色螺旋擴散,有旋轉軌跡
👉 指向POINTINGFireworkUmbrella藍色傘形煙花,拖尾柔和
✋ 張開手掌OPEN_PALMFireworkA隨機色環形爆裂 + 拖尾,基礎通用款

技術上,在入口邏輯裡會根據識別到的手勢型別,對映到不同的觸發器函式,並傳入不同的引數(粒子數量、配色、持續時間等),讓每種手勢都有明顯區別的手感和視覺反饋。


四、手勢識別:怎麼儘量識別得「準一點」?

單純做一個「能識別」的 Demo 很簡單,但要做到「好玩、不煩人」,就必須控制誤識別率和抖動。為此我做了幾層處理邏輯:

1. 多幀平滑 + 穩定幀判定

  • 使用固定長度的歷史幀(例如 smoothingFrames = 10)做平滑
  • 只有連續若干幀(例如 stableFrames = 6)都穩定識別為同一手勢時,才視為「真正識別到」

這樣可以過濾掉短暫的抖動或過渡幀,讓觸發更可控。

2. 動態置信度閾值

不同手勢本身的易混淆程度不一樣,所以採用了區分度更高的閾值設計:

  • 對於容易混的手勢(拳頭、OK、點贊、剪刀手、指向等),閾值設為 0.85
  • 對於張開手掌(OPEN_PALM),閾值略低一點 0.8

同時,還會要求第一名和第二名手勢的置信度差值 ≥ 0.12,避免「半斤八兩」的兩種手勢亂跳。

3. 冷卻機制 + 上升沿觸發

  • 每個識別器有一個預設冷卻時間 cooldownMs = 350ms
  • 只有當「穩定手勢從 A 變為 B」且不在冷卻期內,才會觸發一次煙花

這意味著你可以保持一個手勢不動,煙花不會無限制連發,更像是「一次明確的動作 → 一次清晰的反饋」。


五、渲染層:Canvas 粒子系統的設計思路

視覺部分基於 Canvas 2D 實現了一個輕量的粒子系統:

  • 每個煙花本質上是大量粒子(位置、速度、加速度、顏色、透明度等屬性)的集合

  • 每一幀進行:

    • 粒子位置更新(重力、阻尼、初速度方向等)
    • 透明度 & 尺寸衰減
    • 組合出光暈、拖尾、閃爍等效果

為了保證效能,我做了幾件事:

  1. 批次更新 & 繪製,減少多餘的狀態切換
  2. 針對不同煙花型別,限制最大粒子數量,避免堆爆記憶體
  3. 在多發煙花場景下優先清理已經「看不見」的粒子

在普通筆記本 + 現代瀏覽器環境下,同時存在數千個粒子仍可以保持比較流暢的體驗。


六、專案結構 & 技術棧簡述

專案整體是一個很標準的前端小應用形態:

  • 技術棧

    • 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 或一起玩

關於這篇文章的日期

保留舊站原始文章標註的日期;實際開始寫作的時間可能更早。

原始日期: 2025-11-16 11:06:59 +0800