本文档对 wjgz/wjgz.html 文件的当前功能、实现逻辑及注意事项进行客观描述。
该项目是一个基于 Web 的 3D 交互场景,通过摄像头捕捉用户手势来控制 3D 场景中的物体运动与形态。
- 手势识别系统:利用计算机视觉技术实时分析摄像头输入,识别特定手势。
- 3D 渲染引擎:使用 React 和 Three.js 构建 3D 场景。
- 粒子阵列系统:由数百个独立单元("飞剑")组成的动态阵列,根据手势变换排列方式。
- 手部动画:在 3D 空间中实时映射并渲染用户的手部骨骼结构。
- 线条跳跃效果:在特定状态下,粒子之间产生的动态连线视觉效果。
- 技术栈:使用 MediaPipe Tasks Vision 进行手部特征点检测。
- 状态管理:使用 Zustand 库管理全局状态(如手势模式、追踪状态、目标坐标)。
- 手势判定:通过计算手指关节角度判断手指伸展状态,从而映射为以下模式:
- IDLE (空闲):未检测到手势或默认状态。
- **SHIELD **:握拳触发,粒子排列成半球体。
- **BAGUA **:张开手掌触发,粒子排列成旋转的同心圆环。
- **GIANT_SWORD **:双指(食指+中指)触发,粒子跟随手指移动,形成游龙状路径。
- **MOBIUS **:单指触发,粒子形成螺旋状光束。
- **ROCK_SCATTER **:摇滚手势(食指+小指)触发,粒子进行扩散与重聚。
- 实现方式:
- 获取 MediaPipe 返回的 21 个手部特征点坐标 (Landmarks)。
- 将 2D 屏幕坐标转换为 3D 世界坐标。
- 使用
InstancedMesh渲染关节节点(球体)。 - 使用
LineSegments渲染骨骼连接线。 - 指尖拖尾:在指尖位置添加轨迹渲染组件,记录运动路径。
- 触发条件:仅在
ROCK_SCATTER模式下激活。 - 实现逻辑:
- 每隔特定帧数(如每 2 帧)遍历粒子数组。
- 随机选取粒子作为起点。
- 在一定半径内随机寻找邻近粒子作为终点。
- 更新
BufferGeometry的顶点数据,绘制连接线段。 - 通过随机抖动顶点坐标模拟动态视觉。
- 物理模拟:每个粒子拥有独立的位置、速度和加速度向量。
- 行为算法:
- 追逐行为:粒子根据当前模式计算目标位置,并施加转向力 (Steering Force) 靠近目标。
- 分离行为:在特定模式下(如巨剑身体部分),粒子之间施加排斥力以避免重叠。
- 噪声扰动:引入 Simplex Noise 为运动添加随机性,使其看起来更自然。
- 硬件依赖:必须授予浏览器摄像头权限才能运行手势识别功能。
- 性能因素:
- 粒子数量 (
swordCount) 和历史路径长度直接影响渲染帧率。 线条跳跃效果涉及大量距离计算,已通过降频更新(每 2 帧一次)和限制连接数量来平衡性能。
- 粒子数量 (
- 环境要求:光线不足或背景杂乱可能影响 MediaPipe 的识别准确率,导致手部动画抖动或手势误判。
- 兼容性:代码使用了 ES Modules 和 Import Maps,需在支持现代标准的浏览器中运行。
https://github.com/ktlal/KTL- 感谢佬的手势捕捉的动画