dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
手势控制粒子花朵绽放 · Three.js + MediaPipe Hands + GLSL
用摄像头识别手势,让一朵发光粒子花在你指尖绽放。
握拳 → 花朵收拢成花苞;张开手掌 → 粒子向外绽放;手的位置会带动花朵轻微跟随。 纯 Three.js + MediaPipe Hands + GLSL,无构建步骤,本地起个 HTTP 服务就能跑。
花苞 · 半开 · 绽放
摄像头 API 只在 https 或 localhost 下可用,所以不能直接双击 index.html。
# 方式一:Windows 双击 serve.cmd(自动找 node / python)
# 方式二:手动
node serve.mjs . 8787
# 方式三:只有 Python
python -m http.server 8787 --bind 127.0.0.1
然后打开 http://localhost:8787/,浏览器会请求摄像头权限,允许即可。
依赖已全部本地化到
vendor/(three 0.186、@mediapipe/hands 0.4), 不依赖 CDN,国内网络也能离线跑。约 13MB。
tension 是手掌张开度,范围 0 ~ 1:0 = 握拳,1 = 完全张开。
计算方式(src/hands.js → computeTension):
palmSpan = |wrist(0) − middle_MCP(9)| // 手掌尺度,用于归一化,抵消远近
ratio_i = |wrist(0) − tip_i| / palmSpan // 四指:tip ∈ {8,12,16,20}
meanRatio = mean(ratio_i) // 握拳≈1.2~1.5,张开≈2.2~2.6
raw = clamp((meanRatio − 1.12) / (2.30 − 1.12), 0, 1)
t = smoothstep(raw) // 3t²−2t³,曲线更柔
再做一次时间平滑,避免临界抖动让花朵抽搐:
tension += (target - tension) * 0.18
张开度映射到视觉(src/main.js):
| tension | 状态 |
|---|---|
< 0.32 | 花苞闭合 |
0.32 ~ 0.66 | 平滑过渡(花瓣扭转外翻) |
> 0.66 | 完全绽放 |
绽放程度本身用需求指定的缓动:
spread += (targetSpread - spread) * 0.1
| 参数 | 默认 | 说明 |
|---|---|---|
count | 16000 | 粒子数量,范围 5000~20000 |
petals | 6 | 花瓣数量,3~12 |
radius | 1.95 | 花朵半径 |
seed | 20261023 | 随机种子,同种子生成同一朵花 |
spread | — | 固定绽放程度(0~1),用于截图/调参 |
camera | — | off 关闭摄像头,进入鼠标模式 |
debug | — | 1 显示 fps / spread / 手部状态 |
例:http://localhost:8787/?count=20000&petals=8&spread=0.8
| 键 | 作用 |
|---|---|
L | 显示 / 隐藏 21 点手部骨架 |
V | 摄像头在小窗 与 低透明度全屏背景 之间切换 |
D | 调试信息 |
R | 重连摄像头 |
花瓣形状(src/flower.js)用显式参数化,而不是"半径阈值":
u ∈ [0,1] 沿花瓣,0 = 花心,1 = 尖端
v ∈ [-1,1] 横向,±1 是花瓣边缘
halfW(u) = 0.52 · sin(π·u^0.75)^0.70 · (1 − 0.16u)
θ = p·2π/P + tilt[p] + v · halfW(u)
r = R · len[p] · (0.10 + 0.90u)
每片花瓣的长度/角度都有 ±6% 抖动,避免"完美对称的假花"。
花苞用同一套 θ / u 参数,只是收进一个竖立的水滴轮廓(上下收敛、中段最宽)
并按高度绕垂直轴扭转——所以中间态看到的是花瓣向外翻开,而不是一团球膨大。
位置插值全部在顶点着色器(src/shaders.js)完成:CPU 每帧只更新
uSpread / uTime / uHand 三个 uniform,16k 粒子也不会有 JS 开销。
错峰绽放:每颗粒子按 aRho、aSeed 分配一点点延迟,花心先开、瓣尖后开,
中间态才不是一团模糊。叠加混合(additive)容易过曝,所以单颗粒子压得很暗、
靠数量堆出光感,并且花苞态整体压暗、绽放态提亮,保证两种状态的亮度都稳定。
配色(顶点着色器 palette(),按 aRho 分层):
| 区域 | 颜色 | 占比 |
|---|---|---|
| 花心 | #FF9ECF + #A7E8FF | 点缀 |
| 花瓣主体 | #FF7AB6 → #FF9ECF | ~60% |
| 花瓣外缘 | #8FD3FF → #B388FF | ~25% |
| 最外一圈 | #9B6BFF | ~15% |
不用深蓝、荧光绿、暖黄,底色纯黑。
gesture-flower/
├─ index.html 页面骨架 + importmap
├─ serve.cmd Windows 一键起服务
├─ serve.mjs 零依赖静态服务器(正确 MIME,含 .wasm/.data)
├─ src/
│ ├─ main.js 场景、动画循环、HUD、骨架绘制、兜底交互
│ ├─ flower.js 粒子几何:花瓣/花蕊/花苞/背景星尘
│ ├─ hands.js MediaPipe 封装 + tension 计算
│ ├─ shaders.js 顶点/片元着色器(GLSL)
│ └─ style.css HUD 与响应式
├─ vendor/
│ ├─ three/ three.module.js + three.core.js
│ └─ mediapipe/ hands.js + wasm/data(SIMD 版)
└─ docs/ 截图
getUserMedia。localhost 除外),并且只有前/后摄像头之一会被打开。maxNumHands: 1),多人场景取画面里最靠前的一只。MIT(见 LICENSE)。第三方:
three.js(MIT)、
MediaPipe Hands(Apache-2.0)。
vendor/ 下为两者的原样分发,遵循各自许可。
页面不强制摄像头,进来先是可以直接玩的开始界面:
线上地址走 GitHub Pages,是 https,所以手机上摄像头也能直接用: https://rafayellllllllllllll.github.io/gesture-flower/
性能:手机自动降到 10000 粒子并把渲染分辨率限制在 1.6× DPR,保证 60fps 手感。