Extensible Plugin Platform for 3D Hand Interaction
A modular SDK and showcase app that enables custom gesture detection, 3D interactions, and physics engine integration through a powerful plugin system.
Quick Start โข SDK Packages โข Plugin System โข Features โข Usage
HandTrack3D is both a modular SDK and showcase application for building natural user interfaces in 3D environments. The SDK provides an extensible plugin platform for custom gesture detection, 3D interactions, and physics engine integration, while the showcase app demonstrates these capabilities in action.
- ๐ Plugin System - Custom gestures, interactions, and physics adapters
- ๐ฆ Modular Packages - Core, React, Three.js, and Rapier integrations
- ๐ฏ Priority-Based Detection - Configure gesture matching order (0-100 scale)
- โ๏ธ Physics Abstraction - Engine-agnostic physics with adapters (Rapier, Cannon.js)
- ๐ง Framework Agnostic - Use with any JavaScript framework or vanilla JS
- ๐ TypeScript First - Full type safety with comprehensive definitions
- ๐งช Well Tested - 40+ unit tests, integration tests, 90%+ coverage
- โ Real-time hand tracking (30fps) with MediaPipe Hands
- ๐ฏ 3D cursor mapping from 2D hand landmarks to 3D space
- ๐ Gesture recognition (pinch, open hand, fist, point)
- ๐ฎ Object interaction (grab, drag, release, throw)
- ๐๏ธ Multi-hand support (up to 2 hands simultaneously)
- โ๏ธ Physics simulation (gravity, collisions, realistic motion)
- ๐จ Visual feedback with color-coded cursors and trails
- ๐ Real-time stats (FPS, hand count, gestures)
HandTrack3D is available as a set of npm packages for building your own hand tracking applications:
# Install all packages
npm install @handtrack3d/core@alpha
npm install @handtrack3d/react@alpha
npm install @handtrack3d/three@alpha
npm install @handtrack3d/rapier@alphaHandTrack3D's plugin architecture allows you to extend functionality without modifying core code.
import { GestureDetector, GesturePlugin } from '@handtrack3d/core';
class ThumbsUpPlugin implements GesturePlugin {
readonly name = 'custom:thumbs-up';
readonly priority = 70;
readonly gestureType = 'thumbs-up';
detect(landmarks, settings) {
const thumbUp = landmarks[4].y < landmarks[2].y;
const fingersCurled = /* check other fingers */;
return thumbUp && fingersCurled;
}
}
const detector = new GestureDetector();
detector.registerGesture(new ThumbsUpPlugin());
const gesture = detector.detectGesture(landmarks); // Can detect 'thumbs-up'import { GrabPlugin, RapierAdapter } from '@handtrack3d/rapier';
const adapter = new RapierAdapter();
const grabPlugin = new GrabPlugin(adapter, {
grabRadius: 0.5,
throwVelocityScale: 60,
});
// In render loop
grabPlugin.update(hand, rigidBodies);- GesturePlugin - Custom gesture detection with priority-based matching
- InteractionPlugin - 3D interaction behaviors (point-select, custom controls)
- PhysicsAdapter - Physics engine abstraction (Rapier, Cannon.js, Ammo.js)
See examples/ for complete tutorials on building custom plugins.
- Node.js 18+ or pnpm
- Modern browser (Chrome/Edge recommended)
- Webcam
cd ~/Projects/Active/HandTrack3D
pnpm install
pnpm devNavigate to http://localhost:5173 and allow webcam access.
- Show your hand to the webcam
- Pinch (touch thumb and index finger) near an object to grab it
- Move your hand to drag the object in 3D space
- Open your hand (spread all fingers) to release
- Drop or throw - released objects fall with gravity and can be thrown with velocity
- Gravity (9.81 m/sยฒ) - Objects fall naturally when released
- Collisions - Objects bounce off each other and the ground (0.5 restitution)
- Throwing - Release objects while moving to launch them with velocity
- Ground plane - Invisible floor prevents objects from falling forever
- Realistic motion - Damping and friction create natural movement
| Key | Action |
|---|---|
H |
Toggle status panel |
Space |
Reset camera (planned) |
| Input | Action |
|---|---|
| Left click + drag | Rotate camera |
| Right click + drag | Pan camera |
| Scroll wheel | Zoom in/out |
| Gesture | Detection | Visual Feedback |
|---|---|---|
| Pinch | Thumb-index distance < 0.05 | Orange, smaller cursor |
| Open Hand | All fingers extended (>160ยฐ) | Larger cursor, dimmer glow |
| Fist | All fingers curled near wrist | Red, medium cursor |
| None | Default state | Base color (green/blue) |
- React 19 - UI framework
- TypeScript 6 - Type safety
- Vite 8 - Build tool and dev server
- Three.js 0.180 - 3D rendering engine
- React Three Fiber 9.7 - React renderer for Three.js
- @react-three/drei - Three.js helpers and components
- @react-three/rapier - Physics engine integration
- MediaPipe Hands - Hand tracking (21 3D landmarks per hand)
- @mediapipe/camera_utils - Webcam integration
- Loaded via CDN for compatibility
-
Zustand - Lightweight state management
-
handTrackingStore- Hand positions and tracking data -
sceneStore- 3D objects and grab state -
useGestureStore- Gesture detection state -
useHandCursorStore- 3D cursor positions
-
- Tailwind CSS 3 - Utility-first CSS
- PostCSS + Autoprefixer - CSS processing
Webcam (30fps)
โ
MediaPipe Hands (CDN)
โ
handTrackingStore (21 landmarks ร 2 hands)
โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโ
โ โ โ
Gesture Detection Hand-to-3D Mapping HandOverlay (2D)
(pinch/open/fist) (screenโworld) (skeleton viz)
โ โ
useGestureStore useHandCursorStore
โ โ
โโโโโโโโโโฌโโโโโโโโโ
โ
InteractiveObject
(collision, grab, drag)
โ
sceneStore (object positions)
โ
Scene3D (R3F Canvas, 60fps)
HandTrack3D/
โโโ packages/ # SDK packages
โ โโโ core/ # @handtrack3d/core
โ โ โโโ src/
โ โ โ โโโ plugins/ # Plugin system
โ โ โ โ โโโ types.ts # Plugin interfaces
โ โ โ โ โโโ registry.ts # Plugin registry
โ โ โ โโโ gestures/ # Gesture detection
โ โ โ โ โโโ detector.ts # GestureDetector class
โ โ โ โ โโโ plugins/ # Built-in gesture plugins
โ โ โ โโโ tracking/ # MediaPipe integration
โ โ โ โโโ utils/ # Coordinate mapping
โ โ โ โโโ types/ # TypeScript definitions
โ โ โโโ package.json
โ โโโ react/ # @handtrack3d/react
โ โ โโโ src/
โ โ โ โโโ hooks/ # React hooks
โ โ โ โโโ components/ # React components
โ โ โโโ package.json
โ โโโ three/ # @handtrack3d/three
โ โ โโโ src/
โ โ โ โโโ interactions/ # 3D interaction plugins
โ โ โ โโโ utils/ # Three.js utilities
โ โ โโโ package.json
โ โโโ rapier/ # @handtrack3d/rapier
โ โโโ src/
โ โ โโโ adapters/ # Physics adapters
โ โ โโโ interactions/ # Grab plugin
โ โ โโโ hooks/ # React physics hooks
โ โ โโโ utils/ # Physics utilities
โ โโโ package.json
โโโ src/ # Showcase app
โ โโโ components/
โ โ โโโ HandTrackingCanvas/ # 3D scene and rendering
โ โ โ โโโ HandTrackingCanvas.tsx
โ โ โ โโโ Scene3D.tsx
โ โ โ โโโ HandMesh.tsx # 3D cursor with trails
โ โ โ โโโ InteractiveObject.tsx
โ โ โโโ WebcamFeed/ # Webcam and overlay
โ โ โ โโโ WebcamFeed.tsx
โ โ โ โโโ HandOverlay.tsx # 2D skeleton visualization
โ โ โโโ ControlPanel/ # Status UI
โ โโโ hooks/
โ โ โโโ useWebcam.ts # Camera access
โ โ โโโ useHandTracking.ts # MediaPipe integration
โ โ โโโ useHandTo3DMapping.ts # 2Dโ3D coordinate mapping
โ โ โโโ useGestureRecognition.ts
โ โ โโโ useKeyboardShortcuts.ts
โ โโโ stores/
โ โ โโโ handTrackingStore.ts
โ โ โโโ sceneStore.ts
โ โโโ utils/
โ โโโ collisionDetection.ts # Proximity detection
โโโ examples/ # Plugin tutorials
โ โโโ custom-gesture-plugin.md
โ โโโ custom-interaction-plugin.md
โ โโโ custom-physics-adapter.md
โโโ public/ # Static assets
Converts MediaPipe's normalized 2D coordinates (0-1) to 3D world space:
- Convert to NDC (-1 to 1)
- Unproject through camera to get direction vector
- Use MediaPipe z-coordinate for depth (5-10 units from camera)
- Project along direction to final 3D position
- Pinch: Distance between thumb tip (4) and index tip (8) < 0.05
- Open Hand: All finger joint angles > 160ยฐ (extended)
- Fist: All fingertips within 0.15 units of wrist (curled)
- Debouncing: 100ms to prevent flicker
- Proximity: 3D distance between hand cursor and object < 1.5 units
- Grab offset: Store vector from hand to object center
- Drag: Update object position = hand position + grab offset
- โ Chrome 90+ (full support, best performance)
- โ Edge 90+ (full support)
-
โ ๏ธ Firefox 88+ (MediaPipe may have minor issues) -
โ ๏ธ Safari 14+ (WebGL limitations, reduced performance)
- WebGL 2.0 support
- WebRTC (getUserMedia) for webcam
- ES2020+ JavaScript features
- Check permissions: Browser must have webcam access
-
HTTPS required: Some browsers block webcam on
http://(uselocalhost) - Try different browser: Chrome/Edge have best compatibility
- Lighting: Ensure good lighting on your hand
- Distance: Keep hand 1-3 feet from webcam
- Background: Plain background helps detection
- Refresh page: MediaPipe may need reload if it fails to initialize
- Close other tabs: MediaPipe is CPU-intensive
- Reduce hands: Better performance with 1 hand vs 2
- Lower quality: Check webcam settings (720p vs 1080p)
- Hardware acceleration: Enable in browser settings
- Check gesture: Ensure pinch is detected (status panel shows gesture)
- Distance: Move hand closer to object (within 1.5 unit sphere)
- Open hand to release: Spread all fingers to drop object
- CDN issue: Check network tab for failed script loads
- Use VPN: Some regions may block CDN
- Local hosting: Download MediaPipe files for offline use
- โ Hand tracking: 30fps target (debounced updates)
- โ 3D rendering: 60fps (separate from tracking)
- โ Gesture detection: 100ms debounce
- โ Smooth cursor interpolation (lerp 0.3)
- โ Trail effects optimized (10 segments)
pnpm dev # Start dev server (port 5173)
pnpm build # Build for production
pnpm preview # Preview production buildUsing the Plugin System (Recommended):
import { GesturePlugin } from '@handtrack3d/core';
class MyCustomGesture implements GesturePlugin {
readonly name = 'custom:my-gesture';
readonly priority = 50;
readonly gestureType = 'my-gesture';
detect(landmarks, settings) {
// Your detection logic
return /* boolean */;
}
}
// Register with detector
detector.registerGesture(new MyCustomGesture());Direct Modification (Legacy):
- Add gesture type to
src/types/gesture.types.ts - Implement detection in
src/services/gestureDetector.ts - Add visual feedback in
src/components/HandTrackingCanvas/HandMesh.tsx
- Define object in
src/types/scene.types.ts - Add to initial state in
src/stores/sceneStore.ts - Update
InteractiveObject.tsxgeometry rendering
- โ Plugin system architecture
- โ Physics simulation (gravity, collisions, throwing)
- โ Rapier physics adapter
- โ Custom gesture plugins (GesturePlugin interface)
- โ Custom interaction plugins (InteractionPlugin interface)
- โ Physics abstraction (PhysicsAdapter interface)
- โ Multi-hand support (up to 2 hands)
- โ npm packages published
- Plugin marketplace / discovery
- Additional physics adapters (Cannon.js, Ammo.js official support)
- More gesture plugins (swipe, rotate, pinch-to-zoom, two-hand gestures)
- Performance profiling tools
- Plugin debugging utilities
- Settings panel UI (sensitivity, detection thresholds)
- Custom object creation UI
- Multi-user collaboration
- VR/AR integration
- Gesture recording and playback
- Example scenes (playground, tutorials)
- GitHub: kentin0-fiz0l/HandTrack3D
- Issues: Report a bug or request a feature
- Releases: View releases
- @handtrack3d/core - Core hand tracking and gesture detection
- @handtrack3d/react - React hooks and components
- @handtrack3d/three - Three.js integration
- @handtrack3d/rapier - Rapier physics adapter
MIT License - See LICENSE file for details.
- MediaPipe by Google for hand tracking ML models
- Three.js community for 3D rendering
- React Three Fiber for declarative Three.js
- Rapier for high-performance physics simulation
- Built with Claude Opus 4.6 assistance
v0.2.0-alpha.0 โข Plugin System Complete โข Built with โค๏ธ using TypeScript, React, Three.js, and MediaPipe