|
|
@ -31,6 +31,10 @@ export enum HandGesture { |
|
|
|
DELETE_GESTURE = "delete_gesture", |
|
|
|
|
|
|
|
OTHER = "other", |
|
|
|
|
|
|
|
// 游戏手势
|
|
|
|
DIRECTION_RIGHT = "direction_right", |
|
|
|
JUMP = "jump", // 食指 + 拇指上抬
|
|
|
|
} |
|
|
|
|
|
|
|
interface HandLandmark { |
|
|
@ -203,6 +207,8 @@ export class Detector { |
|
|
|
const fingers = this._fingersUp(hand); |
|
|
|
const fingerState = fingers.join(","); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 定义手势映射表
|
|
|
|
const gestureMap = new Map<string, HandGesture>([ |
|
|
|
// 食指举起,移动鼠标
|
|
|
@ -226,6 +232,7 @@ export class Detector { |
|
|
|
|
|
|
|
// 其他手势
|
|
|
|
["0,0,0,0,0", HandGesture.VOICE_GESTURE_STOP], |
|
|
|
["1,1,1,0,0", HandGesture.JUMP], |
|
|
|
]); |
|
|
|
|
|
|
|
if (gestureMap.has(fingerState)) { |
|
|
@ -237,6 +244,12 @@ export class Detector { |
|
|
|
return HandGesture.DELETE_GESTURE; |
|
|
|
} |
|
|
|
|
|
|
|
// 检查右边手势
|
|
|
|
if (this._isRightGesture(hand, fingers)) { |
|
|
|
return HandGesture.DIRECTION_RIGHT; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 返回默认值
|
|
|
|
return HandGesture.OTHER; |
|
|
|
} |
|
|
@ -262,6 +275,26 @@ export class Detector { |
|
|
|
return isThumbExtended && areOtherFingersClosed && isThumbLeftmost; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static _isRightGesture(hand: HandInfo, fingers: number[]): boolean { |
|
|
|
const THUMB_INDEX = 4; |
|
|
|
const FINGER_TIPS = [8, 12, 16, 20]; |
|
|
|
const distance_threshold = 0.05; |
|
|
|
|
|
|
|
const isThumbExtended = fingers[0] === 1; |
|
|
|
const areOtherFingersClosed = fingers |
|
|
|
.slice(1) |
|
|
|
.every((finger) => finger === 0); |
|
|
|
const isThumbRightmost = FINGER_TIPS.every( |
|
|
|
(tipIndex) => |
|
|
|
hand.landmarks[THUMB_INDEX].x < |
|
|
|
hand.landmarks[tipIndex].x - distance_threshold |
|
|
|
); |
|
|
|
|
|
|
|
return isThumbExtended && areOtherFingersClosed && isThumbRightmost; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 处理检测结果并执行相应动作 |
|
|
|
*/ |
|
|
|