p5-phone 1.4.4 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +270 -8
- package/dist/p5-phone.js +630 -2
- package/dist/p5-phone.min.js +3 -3
- package/examples/Phone Sensor Examples/microphone/01_mic_level/index.html +2 -2
- package/examples/Phone Sensor Examples/movement/01_orientation_basic/index.html +1 -1
- package/examples/Phone Sensor Examples/movement/02_rotational_velocity/index.html +1 -1
- package/examples/Phone Sensor Examples/movement/03_acceleration/index.html +1 -1
- package/examples/Phone Sensor Examples/sound/01_dual_audio/index.html +1 -1
- package/examples/Phone Sensor Examples/sound/02_volume_touches/index.html +1 -1
- package/examples/Phone Sensor Examples/touch/01_touch_basic/index.html +1 -1
- package/examples/Phone Sensor Examples/touch/02_touch_zones/index.html +1 -1
- package/examples/Phone Sensor Examples/touch/03_touch_count/index.html +1 -1
- package/examples/Phone Sensor Examples/touch/04_touch_distance/index.html +1 -1
- package/examples/Phone Sensor Examples/touch/05_touch_angle/index.html +1 -1
- package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/README.md +51 -0
- package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/index.html +28 -0
- package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/sketch.js +177 -0
- package/examples/Phone Sensor Examples - Minimal/microphone/01_mic_level/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/movement/01_orientation_basic/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/movement/02_rotational_velocity/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/movement/03_acceleration/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/sound/01_sound_basic/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/sound/02_sound_amplitude/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/touch/01_touch_basic/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/touch/02_touch_zones/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/touch/03_touch_count/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/touch/04_touch_distance/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/touch/05_touch_angle/index.html +1 -1
- package/examples/Phone Sensor Examples - Minimal/vibration/01_haptic_feedback/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/vibration/01_haptic_feedback/sketch.js +87 -0
- package/examples/Phone and Gif/collision/index.html +1 -1
- package/examples/Phone and Gif/fetch/index.html +1 -1
- package/examples/Phone and Gif/fly/index.html +1 -1
- package/examples/Phone and Gif/roll/index.html +1 -1
- package/examples/UXcompare/button-vs-movement/index.html +1 -1
- package/examples/UXcompare/button-vs-orientation/index.html +1 -1
- package/examples/UXcompare/button-vs-shake/index.html +1 -1
- package/examples/UXcompare/gyroscope-demo/index.html +1 -1
- package/examples/UXcompare/microphone-demo/index.html +1 -1
- package/examples/UXcompare/slider-vs-angle/index.html +1 -1
- package/examples/UXcompare/slider-vs-distance/index.html +1 -1
- package/examples/UXcompare/slider-vs-microphone/index.html +1 -1
- package/examples/UXcompare/slider-vs-touches/index.html +1 -1
- package/examples/UXcompare/sliders-vs-acceleration/index.html +1 -1
- package/examples/UXcompare/sliders-vs-rotation/index.html +1 -1
- package/examples/blankTemplate/index.html +1 -1
- package/examples/homepage/index.html +824 -88
- package/examples/workArea/01_camera-selector/README.md +119 -0
- package/examples/workArea/01_camera-selector/index.html +28 -0
- package/examples/workArea/01_camera-selector/sketch.js +239 -0
- package/examples/workArea/03_facemesh-nose/index.html +34 -0
- package/examples/workArea/03_facemesh-nose/sketch.js +247 -0
- package/examples/workArea/03_facemesh-nose-preload/index.html +34 -0
- package/examples/workArea/03_facemesh-nose-preload/sketch.js +173 -0
- package/examples/workArea/04_facemesh-FINAL/README.md +85 -0
- package/examples/workArea/04_facemesh-FINAL/index.html +31 -0
- package/examples/workArea/04_facemesh-FINAL/sketch.js +240 -0
- package/examples/workArea/04_facemesh-simplified_temp/README.md +93 -0
- package/examples/workArea/04_facemesh-simplified_temp/index.html +31 -0
- package/examples/workArea/04_facemesh-simplified_temp/sketch.js +259 -0
- package/examples/workArea/05_handpose/extra.js +0 -0
- package/examples/workArea/05_handpose/index.html +31 -0
- package/examples/workArea/05_handpose/sketch.js +362 -0
- package/examples/workArea/05_handpose-preload/index.html +31 -0
- package/examples/workArea/05_handpose-preload/sketch.js +362 -0
- package/examples/workArea/06_bodypose-FINAL/index.html +31 -0
- package/examples/workArea/06_bodypose-FINAL/sketch.js +360 -0
- package/package.json +5 -5
- package/src/p5-phone.js +630 -2
- package/src/permissionMic.js +0 -240
- package/src/permissionsGesture.js +0 -213
- package/src/permissionsGyro.js +0 -246
package/README.md
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
# p5-phone
|
|
2
|
-

|
|
3
|
+
*Illustration by [Angela Torchio](https://angelatorchio.com/)*
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
## [Link for Interactive Examples](https://digitalfuturesocadu.github.io/P5-Phone-Interactions/examples/homepage)
|
|
5
|
+
## [Link for Interactive Examples](https://npuckett.github.io/p5-phone/examples/homepage)
|
|
7
6
|
|
|
8
7
|
# Overview
|
|
9
8
|
P5.js on mobile provides unique opportunities and challenges. The main P5 framework does an excellent job of making it easy to read data from various phone inputs and sensors, however it doesn't deal with the realities of contemporary browser's built in gestures and security protocols.
|
|
10
9
|
That's where this library comes in:
|
|
11
10
|
|
|
12
|
-
- Simplifies accessing phone hardware from the browser (accelerometers, gyroscopes, microphone)
|
|
11
|
+
- Simplifies accessing phone hardware from the browser (accelerometers, gyroscopes, microphone, vibration motor)
|
|
13
12
|
- Simplifies disabling default phone gestures (Zoom, refresh, back, etc)
|
|
14
13
|
- Simplifies enabling audio output
|
|
15
14
|
- Simplifies using an on-screen console to display errors and debug info
|
|
@@ -61,16 +60,17 @@ This library simplifies access to the following p5.js mobile sensor and audio co
|
|
|
61
60
|
- [Motion Sensor Activation](#motion-sensor-activation)
|
|
62
61
|
- [Microphone Activation](#microphone-activation)
|
|
63
62
|
- [Sound Output Activation](#sound-output-activation)
|
|
63
|
+
- [Vibration Motor (Android Only)](#vibration-motor-android-only)
|
|
64
64
|
- [Debug System](#debug-system)
|
|
65
65
|
|
|
66
66
|
### CDN (Recommended)
|
|
67
67
|
|
|
68
68
|
```html
|
|
69
69
|
<!-- Minified version (recommended) -->
|
|
70
|
-
<script src="https://cdn.jsdelivr.net/npm/p5-phone@1.
|
|
70
|
+
<script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
|
|
71
71
|
|
|
72
72
|
<!-- Development version (larger, with comments) -->
|
|
73
|
-
<!-- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.
|
|
73
|
+
<!-- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.js"></script> -->
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
### Basic Setup
|
|
@@ -98,7 +98,7 @@ This library simplifies access to the following p5.js mobile sensor and audio co
|
|
|
98
98
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
|
|
99
99
|
|
|
100
100
|
<!-- Load p5-phone library -->
|
|
101
|
-
<script src="https://cdn.jsdelivr.net/npm/p5-phone@1.
|
|
101
|
+
<script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
|
|
102
102
|
|
|
103
103
|
</head>
|
|
104
104
|
<body>
|
|
@@ -192,10 +192,17 @@ enableMicButton(text) // Button-based microphone activation
|
|
|
192
192
|
enableSoundTap(message) // Tap anywhere to enable sound playback
|
|
193
193
|
enableSoundButton(text) // Button-based sound activation
|
|
194
194
|
|
|
195
|
+
// Vibration motor (Android only)
|
|
196
|
+
enableVibrationTap(message) // Tap anywhere to enable vibration
|
|
197
|
+
enableVibrationButton(text) // Button-based vibration activation
|
|
198
|
+
vibrate(pattern) // Trigger vibration (duration or pattern array)
|
|
199
|
+
stopVibration() // Stop any ongoing vibration
|
|
200
|
+
|
|
195
201
|
// Status variables (check these in your code)
|
|
196
202
|
window.sensorsEnabled // Boolean: true when motion sensors are active
|
|
197
203
|
window.micEnabled // Boolean: true when microphone is active
|
|
198
204
|
window.soundEnabled // Boolean: true when sound output is active
|
|
205
|
+
window.vibrationEnabled // Boolean: true when vibration is available (Android only)
|
|
199
206
|
|
|
200
207
|
// Debug system (enhanced in v1.4.0)
|
|
201
208
|
showDebug() // Show on-screen debug panel with automatic error catching
|
|
@@ -226,6 +233,7 @@ this.enableGyroTap('Tap to start');
|
|
|
226
233
|
- `window.sensorsEnabled` - Boolean indicating if motion sensors are active
|
|
227
234
|
- `window.micEnabled` - Boolean indicating if microphone is active
|
|
228
235
|
- `window.soundEnabled` - Boolean indicating if sound output is active
|
|
236
|
+
- `window.vibrationEnabled` - Boolean indicating if vibration is available (Android only)
|
|
229
237
|
|
|
230
238
|
**Usage:**
|
|
231
239
|
```javascript
|
|
@@ -245,6 +253,11 @@ function draw() {
|
|
|
245
253
|
// Safe to play sounds
|
|
246
254
|
mySound.play();
|
|
247
255
|
}
|
|
256
|
+
|
|
257
|
+
if (window.vibrationEnabled) {
|
|
258
|
+
// Safe to use vibration (Android only)
|
|
259
|
+
vibrate(50);
|
|
260
|
+
}
|
|
248
261
|
}
|
|
249
262
|
|
|
250
263
|
// You can also use them for conditional UI
|
|
@@ -454,6 +467,255 @@ function mousePressed() {
|
|
|
454
467
|
}
|
|
455
468
|
```
|
|
456
469
|
|
|
470
|
+
### Vibration Motor (Android Only)
|
|
471
|
+
|
|
472
|
+
**Purpose:** Access the device's vibration motor for haptic feedback and tactile interactions.
|
|
473
|
+
|
|
474
|
+
**⚠️ Platform Support:**
|
|
475
|
+
- ✅ **Android** - Full support in Chrome and most Android browsers
|
|
476
|
+
- ❌ **iOS** - Not supported (Vibration API not available on iOS devices)
|
|
477
|
+
|
|
478
|
+
**Important:** The vibration feature will automatically detect if the device supports vibration. On iOS or unsupported devices, `window.vibrationEnabled` will be `false` and vibration calls will be safely ignored with console warnings.
|
|
479
|
+
|
|
480
|
+
**Commands:**
|
|
481
|
+
- `enableVibrationTap(message)` - Tap anywhere on screen to enable vibration
|
|
482
|
+
- `enableVibrationButton(text)` - Creates a button with custom text to enable vibration
|
|
483
|
+
- `vibrate(pattern)` - Trigger vibration with a duration (ms) or pattern array
|
|
484
|
+
- `stopVibration()` - Stop any ongoing vibration
|
|
485
|
+
|
|
486
|
+
**Usage:**
|
|
487
|
+
```javascript
|
|
488
|
+
function setup() {
|
|
489
|
+
createCanvas(windowWidth, windowHeight);
|
|
490
|
+
|
|
491
|
+
// Enable vibration with tap (Android only)
|
|
492
|
+
enableVibrationTap('Tap to enable vibration');
|
|
493
|
+
|
|
494
|
+
// Or use a button
|
|
495
|
+
// enableVibrationButton('Enable Haptics');
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function draw() {
|
|
499
|
+
background(220);
|
|
500
|
+
|
|
501
|
+
if (window.vibrationEnabled) {
|
|
502
|
+
text('Vibration ready! Tap anywhere', 20, 20);
|
|
503
|
+
} else {
|
|
504
|
+
text('Vibration not available', 20, 20);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function mousePressed() {
|
|
509
|
+
if (window.vibrationEnabled) {
|
|
510
|
+
// Simple vibration - 50ms pulse
|
|
511
|
+
vibrate(50);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
**Vibration Patterns:**
|
|
517
|
+
```javascript
|
|
518
|
+
// Single vibration (duration in milliseconds)
|
|
519
|
+
vibrate(100); // Vibrate for 100ms
|
|
520
|
+
|
|
521
|
+
// Pattern: [vibrate, pause, vibrate, pause, ...]
|
|
522
|
+
vibrate([100, 50, 100]); // Short-short pattern
|
|
523
|
+
vibrate([200, 100, 200, 100, 200]); // Triple pulse
|
|
524
|
+
vibrate([50, 50, 50, 50, 500]); // Quick taps then long
|
|
525
|
+
|
|
526
|
+
// Stop any ongoing vibration
|
|
527
|
+
stopVibration();
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**Common Use Cases:**
|
|
531
|
+
```javascript
|
|
532
|
+
// Haptic feedback for button presses
|
|
533
|
+
function mousePressed() {
|
|
534
|
+
if (window.vibrationEnabled) {
|
|
535
|
+
vibrate(20); // Quick tap feedback
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Touch zones with different haptic patterns
|
|
540
|
+
function touchStarted() {
|
|
541
|
+
if (window.vibrationEnabled) {
|
|
542
|
+
if (mouseX < width/2) {
|
|
543
|
+
vibrate(50); // Left side - short pulse
|
|
544
|
+
} else {
|
|
545
|
+
vibrate([50, 30, 50]); // Right side - double pulse
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return false;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// Collision detection
|
|
552
|
+
function checkCollision() {
|
|
553
|
+
if (collision && window.vibrationEnabled) {
|
|
554
|
+
vibrate([100, 50, 100, 50, 200]); // Alert pattern
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Game events
|
|
559
|
+
function gameOver() {
|
|
560
|
+
if (window.vibrationEnabled) {
|
|
561
|
+
vibrate(500); // Long vibration for game over
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
**Best Practices:**
|
|
567
|
+
- Use short vibrations (20-100ms) for subtle feedback
|
|
568
|
+
- Use patterns for more complex haptic responses
|
|
569
|
+
- Always check `window.vibrationEnabled` before calling `vibrate()`
|
|
570
|
+
- Don't overuse - vibration can quickly drain battery
|
|
571
|
+
- Test on Android devices as iOS doesn't support vibration
|
|
572
|
+
|
|
573
|
+
### PhoneCamera (ML5 Integration)
|
|
574
|
+
|
|
575
|
+
**Purpose:** Simplified camera access optimized for ML5.js machine learning models (FaceMesh, HandPose, BodyPose, etc.). Handles camera initialization, coordinate mapping, mirroring, and display modes automatically.
|
|
576
|
+
|
|
577
|
+
**Key Features:**
|
|
578
|
+
- **Automatic Coordinate Mapping** - ML5 keypoints automatically mapped to canvas coordinates
|
|
579
|
+
- **Mirror Support** - Handles front camera mirroring for natural interaction
|
|
580
|
+
- **Display Modes** - Multiple video sizing options (fitHeight, cover, contain, fixed)
|
|
581
|
+
- **ML5 Optimized** - Direct integration with ML5 v1.x models
|
|
582
|
+
- **Auto-initialization** - Camera starts automatically when permissions are granted
|
|
583
|
+
|
|
584
|
+
**Commands:**
|
|
585
|
+
|
|
586
|
+
| Function | Purpose | Parameters |
|
|
587
|
+
|----------|---------|------------|
|
|
588
|
+
| `createPhoneCamera(active, mirror, mode)` | Create new camera instance | active: 'user' or 'environment'<br>mirror: true/false<br>mode: 'fitHeight', 'cover', 'contain', 'fixed' |
|
|
589
|
+
| `enableCameraTap(message)` | Tap to enable camera | Optional message string |
|
|
590
|
+
| `cam.onReady(callback)` | Execute code when camera ready | Callback function |
|
|
591
|
+
| `cam.mapKeypoint(keypoint)` | Map single ML5 keypoint to screen | ML5 keypoint object |
|
|
592
|
+
| `cam.mapKeypoints(keypoints)` | Map array of ML5 keypoints | Array of ML5 keypoints |
|
|
593
|
+
|
|
594
|
+
**Properties:**
|
|
595
|
+
|
|
596
|
+
| Property | Description | Type |
|
|
597
|
+
|----------|-------------|------|
|
|
598
|
+
| `cam.ready` | Camera initialization status | Boolean |
|
|
599
|
+
| `cam.video` | p5.js video element | p5.Element |
|
|
600
|
+
| `cam.active` | Current camera ('user'/'environment') | String |
|
|
601
|
+
| `cam.mirror` | Mirror state | Boolean |
|
|
602
|
+
| `cam.mode` | Display mode | String |
|
|
603
|
+
| `cam.width` | Video width | Number |
|
|
604
|
+
| `cam.height` | Video height | Number |
|
|
605
|
+
|
|
606
|
+
**Basic Setup:**
|
|
607
|
+
```javascript
|
|
608
|
+
let cam;
|
|
609
|
+
let facemesh;
|
|
610
|
+
let faces = [];
|
|
611
|
+
|
|
612
|
+
function setup() {
|
|
613
|
+
createCanvas(windowWidth, windowHeight);
|
|
614
|
+
|
|
615
|
+
// Create camera: front camera, mirrored, fit to canvas height
|
|
616
|
+
cam = createPhoneCamera('user', true, 'fitHeight');
|
|
617
|
+
|
|
618
|
+
// Enable camera (auto-starts if permission granted)
|
|
619
|
+
enableCameraTap();
|
|
620
|
+
|
|
621
|
+
// Start ML5 when camera is ready
|
|
622
|
+
cam.onReady(() => {
|
|
623
|
+
let options = {
|
|
624
|
+
maxFaces: 1,
|
|
625
|
+
refineLandmarks: false,
|
|
626
|
+
flipHorizontal: false // cam.mapKeypoint() handles mirroring
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
facemesh = ml5.faceMesh(options, modelLoaded);
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function modelLoaded() {
|
|
634
|
+
// Start detection - use cam.videoElement for ML5
|
|
635
|
+
facemesh.detectStart(cam.videoElement, (results) => {
|
|
636
|
+
faces = results;
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
function draw() {
|
|
641
|
+
background(220);
|
|
642
|
+
|
|
643
|
+
// Draw camera feed
|
|
644
|
+
if (cam.ready) {
|
|
645
|
+
image(cam, 0, 0); // PhoneCamera handles positioning automatically
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Draw tracked face keypoints
|
|
649
|
+
if (faces.length > 0) {
|
|
650
|
+
let face = faces[0];
|
|
651
|
+
|
|
652
|
+
// Map nose tip keypoint (index 1) to screen coordinates
|
|
653
|
+
let nose = cam.mapKeypoint(face.keypoints[1]);
|
|
654
|
+
|
|
655
|
+
// Use coordinates for interaction
|
|
656
|
+
fill(255, 0, 0);
|
|
657
|
+
circle(nose.x, nose.y, 30);
|
|
658
|
+
|
|
659
|
+
// Map all keypoints at once
|
|
660
|
+
let allPoints = cam.mapKeypoints(face.keypoints);
|
|
661
|
+
for (let point of allPoints) {
|
|
662
|
+
circle(point.x, point.y, 3);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
**Display Modes:**
|
|
669
|
+
|
|
670
|
+
| Mode | Behavior |
|
|
671
|
+
|------|----------|
|
|
672
|
+
| `'fitHeight'` | Scale video to canvas height (default, recommended) |
|
|
673
|
+
| `'cover'` | Fill entire canvas (may crop video) |
|
|
674
|
+
| `'contain'` | Fit entire video in canvas (may show letterboxing) |
|
|
675
|
+
| `'fixed'` | Fixed size (set with `cam.fixedWidth`, `cam.fixedHeight`) |
|
|
676
|
+
|
|
677
|
+
**Coordinate Mapping:**
|
|
678
|
+
|
|
679
|
+
The `mapKeypoint()` and `mapKeypoints()` functions automatically handle:
|
|
680
|
+
- Video-to-canvas scaling
|
|
681
|
+
- Mirror transformation (for front camera)
|
|
682
|
+
- Offset positioning (for different display modes)
|
|
683
|
+
- 3D coordinates (preserves z-depth from BlazePose)
|
|
684
|
+
|
|
685
|
+
```javascript
|
|
686
|
+
// Single keypoint
|
|
687
|
+
let nose = cam.mapKeypoint(face.keypoints[1]);
|
|
688
|
+
console.log(nose.x, nose.y, nose.z); // Screen coordinates + depth
|
|
689
|
+
|
|
690
|
+
// Multiple keypoints
|
|
691
|
+
let hands = cam.mapKeypoints(hand.keypoints);
|
|
692
|
+
hands.forEach(point => {
|
|
693
|
+
circle(point.x, point.y, 5);
|
|
694
|
+
});
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
**ML5 Model Examples:**
|
|
698
|
+
|
|
699
|
+
```javascript
|
|
700
|
+
// FaceMesh (468 keypoints)
|
|
701
|
+
let options = { maxFaces: 1, refineLandmarks: false, flipHorizontal: false };
|
|
702
|
+
facemesh = ml5.faceMesh(options, modelLoaded);
|
|
703
|
+
|
|
704
|
+
// HandPose (21 keypoints per hand)
|
|
705
|
+
let options = { maxHands: 2, runtime: 'mediapipe', flipHorizontal: false };
|
|
706
|
+
handpose = ml5.handPose(options, modelLoaded);
|
|
707
|
+
|
|
708
|
+
// BodyPose (33 keypoints with 3D)
|
|
709
|
+
let options = { modelType: 'MULTIPOSE_LIGHTNING', flipped: false };
|
|
710
|
+
bodypose = ml5.bodyPose('BlazePose', options, modelLoaded);
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
**Important Notes:**
|
|
714
|
+
- Always set `flipHorizontal: false` in ML5 options (PhoneCamera handles mirroring)
|
|
715
|
+
- Use `cam.videoElement` (native HTML video element) when passing to ML5's `detectStart()`
|
|
716
|
+
- Check `cam.ready` before using video or drawing keypoints
|
|
717
|
+
- Call `enableCameraTap()` to handle camera permissions automatically
|
|
718
|
+
|
|
457
719
|
### Debug System
|
|
458
720
|
|
|
459
721
|
**Purpose:** Essential on-screen debugging system for mobile development where traditional browser dev tools aren't accessible. Provides automatic error catching, timestamped logging, and color-coded messages.
|