如何在纯前端中通过手势交互来控制星球的转动

如何在纯前端中通过手势交互来控制星球的转动

技术栈

  • MediaPipe Hands - Google 的开源手部追踪库
  • Three.js - 3D 渲染引擎
  • 摄像头实时视频流输入

项目地址粒子土星


手势交互核心实现流程

步骤0:CDN导入

html 复制代码
<!-- MediaPipe 核心库 -->
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.js"></script>

<!-- Three.js (如果需要3D渲染) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>

步骤1: 初始化手势检测器

js 复制代码
const hands = new Hands({
  locateFile: (file) => {
    return `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file}`;
  }
});

hands.setOptions({
  maxNumHands: 1,           // 只检测一只手
  modelComplexity: 1,       // 模型复杂度(0-1)
  minDetectionConfidence: 0.7,  // 检测置信度阈值
  minTrackingConfidence: 0.7    // 追踪置信度阈值
});

步骤2: 启动摄像头并持续检测

js 复制代码
const cameraUtils = new Camera(videoElement, {
  onFrame: async () => {
    await hands.send({ image: videoElement });  // 每帧都发送给模型分析
  },
  width: 640,
  height: 480
});
cameraUtils.start();

步骤3: 处理检测结果 - 两个关键手势映射

🤏 手势1: 缩放控制 (拇指+食指距离)
js 复制代码
// 获取拇指尖端(landmark 4)和食指尖端(landmark 8)
const p1 = hand[4];  // 大拇指指尖
const p2 = hand[8];  // 食指指尖

// 计算两点间的欧氏距离
const dist = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);

// 归一化到 [0, 1] 区间,然后映射到缩放范围 [0.15, 2.5]
const normDist = Math.max(0, Math.min(1, (dist - 0.02) / 0.25));
targetScale = 0.15 + normDist * 2.35;

效果 : 👌捏合手指 = 缩小 | ✋张开手指 = 放大

✋ 手势2: 俯仰角控制 (手掌Y轴位置)
复制代码
// 使用手腕位置(landmark 9)的Y坐标
const y = hand[9].y;  // 手掌中心点

// 归一化Y坐标到 [0, 1],映射到旋转角度 [-0.6, 1.0] 弧度
const normY = Math.max(0, Math.min(1, (y - 0.1) / 0.8));
targetRotX = -0.6 + normY * 1.6;

效果 : 🖐️手掌上移 = 向上看 | 🖐️手掌下移 = 向下看

项目中其他方面设计

平滑动画系统

为了让动作不卡顿,使用了 线性插值(Lerp) :

复制代码
const lerpFactor = 0.08;  // 插值系数,越小越平滑
currentScale += (targetScale - currentScale) * lerpFactor;
currentRotX += (targetRotX - currentRotX) * lerpFactor;

自动巡航模式

当没有检测到手时,进入自动巡航:

js 复制代码
if (!isHandDetected) {
  autoIdleTime += 0.005;
  targetScale = 1.0 + Math.sin(autoIdleTime) * 0.2;      // 自动缩放呼
  吸效果
  targetRotX = 0.4 + Math.sin(autoIdleTime * 0.3) * 0.15; // 自动轻微摇
  摆
}

Shader中的实际应用

手势控制的值最终传递给GPU着色器:

js 复制代码
uniforms.uScale.value = currentScale;      // 控制土星大小
uniforms.uRotationX.value = currentRotX;   // 控制视角俯仰

在GLSL着色器中应用旋转:

js 复制代码
// 处理整体视角的 X 轴旋转(即手势控制的俯仰角)
float cx = cos(uRotationX);
float sx = sin(uRotationX);
float ry = pos.y * cx - pos.z * sx;
float rz = pos.y * sx + pos.z * cx;
pos.y = ry;
pos.z = rz;

作者 :NotSleeply | 项目地址粒子土星

相关推荐
_阿南_6 小时前
项目中新增给AI制定的代码规范
前端·程序员
名字还没想好☜7 小时前
React 实现暗黑模式切换:localStorage 持久化、SSR 首屏闪烁与跟随系统主题
前端·javascript·react.js·ecmascript·react·next.js
console.log('npc')8 小时前
Git 冲突与 AI 协助指南
前端·人工智能·git·大模型
爱学堂IT分享9 小时前
Cesium可视化系统实战课程-Cesium教程学习
前端
糖墨夕10 小时前
理解大语言模型:Agent 的“大脑”
前端·agent
Rain的Java大神之路10 小时前
JavaWeb开发如何解决跨域问题
java·前端·后端·nginx·web安全·面试·运维开发
cpolar技术支持10 小时前
浏览器也能跑本地 AI:用 Transformers.js + WebGPU 做一个最小推理 Demo,cpolar 给同事远程体验
前端·ai·cpolar·webgpu·transformers.js
计算机魔术师12 小时前
OpenAI 发布 GPT-6 Astra:多项基准刷新纪录, cybersecurity 能力达 Critical 阈值
前端
xy345312 小时前
Axure9.0中继器遮罩实现方法
前端·ui·html·axure·原型·产品设计
风骏时光牛马12 小时前
智能任务自动化协同AI工作流
前端