🚀 Advanced Features
Unlock the full potential of Handible with professional-grade audio, loading systems, and advanced interaction features.
🔊 Professional Audio System
Web Audio API Integration
Handible includes a comprehensive audio system built on the Web Audio API for high-quality, low-latency sound effects:
import { audioSystem, AudioSystem } from 'handible';
// Use the global instance
audioSystem.createClickSound(); // 🔊 Button click
audioSystem.createSuccessSound(); // ✅ Success chime
audioSystem.createHoverSound(); // 🎯 Hover feedback
audioSystem.createErrorSound(); // ❌ Error notification
// Volume control
audioSystem.setVolume(0.4); // 🔊 Set to 40%
audioSystem.toggleEnabled(); // 🔄 Toggle on/off
Custom Audio Instances
Create multiple audio systems for different contexts:
// Create a custom audio system for ambient sounds
const ambientAudio = new AudioSystem();
ambientAudio.setVolume(0.2);
// Create a custom audio system for UI sounds
const uiAudio = new AudioSystem();
uiAudio.setVolume(0.6);
Console Controls
For development and debugging, audio controls are available globally:
// Available in browser console
toggleButtonSounds(); // 🔄 Quick toggle
setButtonVolume(0.5); // 🔊 Quick volume adjust
🎬 Loading & Progress System
Scene Loading with Professional Gauges
The built-in loading system provides smooth, animated progress indicators:
import { sceneLoader } from 'handible';
// Show loading for a specific scene
sceneLoader.show('tableScene');
// Manual progress control
sceneLoader.setProgress(25);
sceneLoader.setStage('Loading assets...');
// Animated progress transitions
await sceneLoader.animateProgress(75, 2000); // 75% over 2 seconds
// Hide when complete
sceneLoader.hide();
Realistic Loading Stages
The system includes realistic loading stages that simulate actual loading processes:
// Automatic stages during scene switching:
"Initializing..." → 15%
"Loading models..." → 40%
"Setting up scene..." → 70%
"Finalizing..." → 90%
"Ready!" → 100%
Custom Loading Implementation
async function loadCustomScene() {
sceneLoader.show('customScene');
try {
sceneLoader.setStage('Loading textures...');
await loadTextures();
await sceneLoader.animateProgress(30, 800);
sceneLoader.setStage('Loading models...');
await loadModels();
await sceneLoader.animateProgress(60, 1200);
sceneLoader.setStage('Setting up lighting...');
await setupLighting();
await sceneLoader.animateProgress(85, 600);
sceneLoader.setStage('Ready!');
await sceneLoader.animateProgress(100, 400);
} catch (error) {
sceneLoader.setStage('Error loading scene');
console.error(error);
} finally {
setTimeout(() => sceneLoader.hide(), 500);
}
}
🖥️ Advanced UI Interaction
UI Panel System
Handible provides a sophisticated UI interaction system with palm-activated panels:
// The UI panel appears when the left palm faces the camera
// Features include:
// - Dynamic positioning based on hand location
// - Configurable size (UI_PANEL_WIDTH, UI_PANEL_HEIGHT)
// - Transparent material with customizable appearance
// - Automatic cursor positioning
// - Scene switching buttons
UI Panel Configuration
// Customize UI panel behavior
const UI_PANEL_WIDTH = 1.0; // Panel dimensions
const UI_PANEL_HEIGHT = 0.6;
const UI_CURSOR_SENSITIVITY = 1.0; // Movement sensitivity
const UIBUTTON_HOVER_THRESHOLD = 0.2; // Button interaction precision
Scene Switching Buttons
The UI panel includes built-in scene switching functionality:
// Automatic scene switching buttons:
// � Orange Button → Main Scene (Demo/Whiteboard)
// �🟢 Green Button → Table Scene
// 🔵 Blue Button → Simple Scene
// Buttons automatically:
// - Show loading gauges during transitions
// - Play audio feedback on interaction
// - Handle scene cleanup and re-initialization
// - Parse button actions dynamically (switchToSimpleScene → 'simple')
Error-Resistant Scene Loading
Recent improvements ensure stable scene transitions:
// ✅ Safe material property access
const panel = scene.children.find(obj =>
obj.isMesh && obj.material?.color?.getHex() === 0xbffbff
);
// ✅ Fallback for scenes without interactive surfaces
if (!wallObj && !tableObj && !panel) {
// Provides basic 3D space raycasting for simple scenes
// Prevents crashes in minimal environments
}
// ✅ Proper object disposal and cleanup
// Each scene switch properly disposes previous resources
// Prevents memory leaks and rendering conflicts
🎯 Surface Interaction System
Advanced Surface Registration
The Surface Interaction System allows complex interactions with flat surfaces:
import { SurfaceInteractionSystem } from 'handible';
// Register interactive surfaces
SurfaceInteractionSystem.registerSurface(surface, {
width: 3,
height: 2,
cursorScaleFactor: 2.5,
buttonHoverThreshold: 0.3,
getNormal: (surface) => new THREE.Vector3(0, 0, 1),
getButtonFilter: (obj) => obj.userData.isButton,
handleCursorPosition: (cursorPoint, surface, config) => {
// Custom cursor positioning logic
return worldPosition;
}
});
Multiple Surface Types
Support for different surface configurations:
// Wall/Whiteboard surfaces
surfaceSystem.registerSurface(wallObj, {
width: WHITEBOARD_WIDTH, // 5 units
height: WHITEBOARD_HEIGHT, // 3 units
cursorScaleFactor: CURSOR_SCALE_FACTOR,
buttonHoverThreshold: BUTTON_HOVER_THRESHOLD,
getNormal: (surface) => new THREE.Vector3(0, 0, 1),
getButtonFilter: (obj) => obj.userData.isButton || obj.userData.isKnob
});
// Table surfaces with custom positioning
surfaceSystem.registerSurface(tableObj, {
width: TABLE_WIDTH, // 3 units
height: TABLE_DEPTH, // 2 units
cursorScaleFactor: TABLE_CURSOR_SCALE_FACTOR,
handleCursorPosition: (cursorPoint, surface, config) => {
const scaledX = cursorPoint.x * config.cursorScaleFactor;
const scaledZ = -cursorPoint.y * config.cursorScaleFactor;
const clampedX = Math.max(-config.width / 2, Math.min(config.width / 2, scaledX));
const clampedZ = Math.max(-config.height / 2, Math.min(config.height / 2, scaledZ));
const localPos = new THREE.Vector3(clampedX, 0.1, clampedZ);
return localPos.applyMatrix4(surface.matrixWorld);
}
});
♟️ Chessboard Integration
Advanced Grid System
The library includes special support for chessboard and grid-based interactions:
// Chessboard features include:
// - 8x8 grid system with configurable size
// - Intelligent square highlighting
// - Snap-to-grid positioning
// - Multiple hand interaction support
// - Grabbed object positioning on squares
Chessboard Configuration
const CHESSBOARD_SIZE = 8; // 8x8 grid
const CHESSBOARD_SCALE_FACTOR = 4; // Grid sensitivity
const HIGHLIGHT_COLOR = 0xffff00; // Yellow square highlights
// Automatic features:
// - Square highlighting on hover
// - Cursor snapping to square centers
// - Object placement on grid positions
// - Color state management for squares
Custom Grid Interactions
// The system automatically handles:
// 1. Cursor position mapping to grid coordinates
// 2. Square highlighting with state preservation
// 3. Object snapping to square centers
// 4. Multi-hand grid interaction support
// Access grid data:
import { lastSnappedSquarePerHand } from 'handible';
// Get current grid position for each hand
const hand0Square = lastSnappedSquarePerHand[0]; // {row: 3, col: 4, square: meshRef}
const hand1Square = lastSnappedSquarePerHand[1]; // {row: 1, col: 2, square: meshRef}
🎮 Button Interaction
🎮 Enhanced Button Interaction
Multi-Surface Button Support
The system supports buttons on different surface types with automatic audio feedback:
// Wall buttons (larger threshold)
const wallButtons = wall.children.filter(obj => obj.userData.isButton);
// Table buttons (standard threshold)
const tableButtons = table.children.filter(obj => obj.userData.isButton);
// UI panel buttons (precise threshold)
const uiButtons = panel.children.filter(obj => obj.userData.isUIButton);
// Automatic features for all button types:
// - Hover detection with visual feedback
// - Scale animation on hover (1.1x scale)
// - Color changes (hover colors)
// - Audio feedback on press
// - Distance-based interaction
Button State Management
// Buttons automatically store state information:
button.userData.defaultColor = originalColor; // Preserve original appearance
button.userData.hoverColor = hoverColor; // Define hover appearance
button.userData.isButton = true; // Mark as interactive
button.userData.action = 'customAction'; // Define button action
// Visual feedback system:
// - Scale: 1.0 (normal) → 1.1 (hover) → 1.0 (release)
// - Color: default → hover → default
// - Audio: hover sound → click sound → success sound
Knob and Slider Support
Advanced slider/knob interaction with constrained movement:
// Knobs are automatically detected and handled
knob.userData.isKnob = true;
// Features:
// - Horizontal sliding along predefined track
// - Constrained movement within bounds
// - Visual feedback during manipulation
// - Smooth position updates
// - Audio feedback on interaction
⚙️ Advanced Configuration
Hand Tracking Configuration
Customize various tracking parameters for optimal performance:
const handConfig = {
runningMode: 'VIDEO',
numHands: 2,
minHandDetectionConfidence: 0.5,
minHandPresenceConfidence: 0.5,
minTrackingConfidence: 0.5
};
Interaction Thresholds
Fine-tune interaction distances for different scenarios:
// Different thresholds for different interaction types
const BUTTON_HOVER_THRESHOLD = 0.4; // Wall buttons (larger)
const UIBUTTON_HOVER_THRESHOLD = 0.2; // UI buttons (precise)
const KNOB_HOVER_THRESHOLD = 0.6; // Knobs (medium)
const UI_CURSOR_THRESHOLD = 1.5; // UI activation (wide)
const CLOSE_DISTANCE_THRESHOLD = 3.0; // General interaction
Visual Customization
Customize the appearance of all visual elements:
// Cursor appearance
const CONE_HEIGHT = 0.1; // Cursor size
const CONE_RADIUS = 0.05; // Cursor thickness
const SPHERE_RADIUS = 0.05; // Landmark size
const PALM_SPHERE_RADIUS = 0.03; // Palm indicator size
// Animation settings
const EMA_ALPHA = 0.35; // Smoothing factor (0-1)
const GRAB_SCALE_FACTOR = 3; // Object scaling when grabbed
// Color schemes
const HIGHLIGHT_COLOR = 0xffff00; // Grid highlights (yellow)
// Add custom colors for buttons, cursors, etc.
Performance Optimization
The library includes several performance optimizations:
// Automatic optimizations:
// - Exponential moving average for smooth movement
// - Efficient distance calculations
// - Smart state management
// - Optimized raycasting
// - Selective visual updates
// - Audio context management
// Manual performance controls:
// - Adjustable smoothing factors
// - Configurable update frequencies
// - Optional visual elements
// - Selective surface registration
🔧 Integration Examples
Complete Interactive Scene
import {
startGestureControl,
setSceneObjects,
SurfaceInteractionSystem,
registerOnPinchStart,
audioSystem,
sceneLoader
} from 'handible';
async function setupAdvancedScene() {
// Initialize with loading
sceneLoader.show('advancedScene');
sceneLoader.setStage('Setting up advanced features...');
// Scene setup
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
setSceneObjects({ scene, camera, renderer });
// Hand tracking
await sceneLoader.animateProgress(25, 800);
const video = document.getElementById('webcam');
await startGestureControl(video, scene, 2);
// Audio setup
await sceneLoader.animateProgress(50, 600);
audioSystem.setVolume(0.4);
// Custom surface
await sceneLoader.animateProgress(75, 800);
const customSurface = createCustomSurface();
SurfaceInteractionSystem.registerSurface(customSurface, {
width: 4,
height: 3,
cursorScaleFactor: 2.0,
buttonHoverThreshold: 0.3,
getNormal: () => new THREE.Vector3(0, 1, 0),
getButtonFilter: (obj) => obj.userData.isCustomButton
});
// Interaction callbacks
registerOnPinchStart((handIndex, handedness) => {
audioSystem.createClickSound();
console.log(`Advanced interaction: ${handedness} hand`);
});
sceneLoader.setStage('Ready!');
await sceneLoader.animateProgress(100, 400);
sceneLoader.hide();
console.log('🚀 Advanced scene ready with all features!');
}
xScale: 2, // Horizontal scaling yScale: -2, // Vertical scaling (inverted) zMagnification: 2, // Depth scaling zOffset: 0, // Depth offset rotationOffset: new THREE.Euler(0, 0, 0) // Rotation adjustment };
### Interaction Thresholds
Fine-tune interaction distances and sensitivities:
```javascript
const CLOSE_DISTANCE_THRESHOLD = 3.0; // Object interaction range
const BUTTON_HOVER_THRESHOLD = 0.4; // Button activation distance
const UI_CURSOR_THRESHOLD = 1.5; // UI interaction range
const KNOB_HOVER_THRESHOLD = 0.6; // Knob interaction distance
Performance Optimization
The library includes several optimization features:
- EMA (Exponential Moving Average) smoothing for hand movements
- Scene object caching
- Efficient ray casting
- Anti-flicker mechanisms for UI elements