mediapipe+webgl摄像头识别手掌操控液态流体动画交互效果代码
代码语言:html
所属分类:动画
代码描述:mediapipe+webgl摄像头识别手掌操控液态流体动画交互效果代码,只能通过摄像头来识别双手移动来产生液态气体流动画。
代码标签: mediapipe webgl 摄像头 识别 手掌 操控 液态 流体 动画 交互
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>MediaPipe Fluid Control</title>
<!-- 1. 引入依赖库 (CDN) -->
<!-- GUI 控制面板 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.9/dat.gui.min.js"></script>
<!-- MediaPipe 核心库 -->
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/control_utils/control_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.js" crossorigin="anonymous"></script>
<style>
html, body {
overflow: hidden;
background-color: #000;
margin: 0;
width: 100%;
height: 100%;
}
canvas {
width: 100%;
height: 100%;
display: block;
}
/* 隐藏用于计算的视频元素 */
.input_video {
display: none;
}
/* 调整 GUI 位置 */
.dg.ac {
z-index: 999 !important;
}
</style>
</head>
<body>
<!-- 渲染画布 -->
<canvas></canvas>
<!-- 摄像头输入源 -->
<video class="input_video"></video>
<script>
'use strict';
// 定义全局 canvas 变量,供 WebGL 和 MediaPipe 使用
var canvas = document.getElementsByTagName('canvas')[0];
var videoElement = document.getElementsByClassName('input_video')[0];
// ==========================================
// 1. MediaPipe 手势识别逻辑
// ==========================================
// 初始化 Hands 模型
const hands = new Hands({locateFile: (file) => {
return `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file}`;
}});
hands.setOptions({
maxNumHands: 2, // 最多识别2只手
modelComplexity: 1, // 模型复杂度,1是平衡,0是快但精度低
minDetectionConfidence: 0.5,
minTrackingConfidence: 0.5
});
hands.onResults(onHandsResults);
// 初始化摄像头
const camera = new Camera(videoElement, {
onFrame: async () => {
await hands.send({image: videoElement});
},
width: 640,
height: 480
});
camera.start();
// 处理手势识别结果
function onHandsResults(results) {
if (results.multiHandLandmarks) {
// 确保 pointers 数组足够容纳识别到的手
while (pointers.length < results.multiHandLandmarks.length) {
pointers.push(new pointerPrototype());
}
// 遍历每一只识别到的手
for (let i = 0; i < pointers.length; i++) {
if (i < results.multiHandLandmarks.length) {
const landmarks = results.multiHandLandmarks[i];
// 使用中指根部 (索引 9) 作为控制点,比指尖更稳定
const handPoint = landmarks[9];
// 坐标映射:
// MediaPipe x: 0(左) -> 1(右)
// 镜像反转 x: (1.0 - x) 以符合人类对镜子的直觉
// 修复点:这里之前使用了 canvasElement 导致报错,现在统一为 canvas
const posX = (1.0 - handPoint.x) * canvas.width;
const posY = handPoint.y * canvas.height;
const pointer = pointers[i];
// 模拟鼠标交互逻辑
if (!pointer.down) {
// 手刚出现,视为“按下”
updatePointerDownData(pointer, i, posX, posY);
} else {
// 手移动中,视为“拖拽”
updatePointerMoveData(pointer, posX, posY);
}
} else {
// 如果这只手消失了,视为“抬起”
if (pointers[i].down) {
updatePointerUpData(pointers[i]);
}
}
}
}
}
// ==========================================
// 2. WebGL 流体模拟引擎 (核心算法)
// ==========================================
resizeCanvas();
var config = {
SIM_RESOLUTION: 128,
DYE_RESOLUTION: 1024,
CAPTURE_RESOLUTION: 512,
DENSITY_DISSIPATION: 1,
VELOCITY_DISSIPATION: 0.2,
PRESSURE: 0.8,
PRESSURE_ITERATIONS: 20,
CURL: 30,
SPLAT_RADIUS: 0.25,
SPLAT_FORCE: 6000,
SHADING: true,
COLORFUL: true,
COLOR_UPDATE_SPEED: 10,
PAUSED: false,
BACK_COLOR: { r: 0, g: 0, b: 0 },
TRANSPARENT: false,
BLOOM: true,
BLOOM_ITERATIONS: 8,
BLOOM_RESOLUTION: 256,
BLOOM_INTENSITY: 0.8,
BLOOM_THRESHOLD: 0.6,
BLOOM_SOFT_KNEE: 0.7,
SUNRAYS: true,
SUNRAYS_RESOLUTION: 196,
SUNRAYS_WEIGHT: 1.0,
}
function pointerPrototype () {
this.id = -1;
this.texcoordX = 0;
this.texcoordY = 0;
this.prevTexcoordX = 0;
this.prevTexcoordY = 0;
this.deltaX = 0;
this.deltaY = 0;
this.down = false;
this.moved = false;
this.color = [30, 0, 300];
}
var pointers = [];
var splatStack = [];
pointers.push(new pointerPrototype());
var ref = getWebGLContext(canvas);
var gl = ref.gl;
var ext = ref.ext;
if (isMobile()) {
config.DYE_RESOLUTION = 512;
}
if (!ext.supportLinearFiltering) {
config.DYE_RESOLUTION = 512;
config.SHADING = false;
config.BLOOM = false;
config.SUNRAYS.........完整代码请登录后点击上方下载按钮下载查看
















网友评论0