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.
Files changed (72) hide show
  1. package/README.md +270 -8
  2. package/dist/p5-phone.js +630 -2
  3. package/dist/p5-phone.min.js +3 -3
  4. package/examples/Phone Sensor Examples/microphone/01_mic_level/index.html +2 -2
  5. package/examples/Phone Sensor Examples/movement/01_orientation_basic/index.html +1 -1
  6. package/examples/Phone Sensor Examples/movement/02_rotational_velocity/index.html +1 -1
  7. package/examples/Phone Sensor Examples/movement/03_acceleration/index.html +1 -1
  8. package/examples/Phone Sensor Examples/sound/01_dual_audio/index.html +1 -1
  9. package/examples/Phone Sensor Examples/sound/02_volume_touches/index.html +1 -1
  10. package/examples/Phone Sensor Examples/touch/01_touch_basic/index.html +1 -1
  11. package/examples/Phone Sensor Examples/touch/02_touch_zones/index.html +1 -1
  12. package/examples/Phone Sensor Examples/touch/03_touch_count/index.html +1 -1
  13. package/examples/Phone Sensor Examples/touch/04_touch_distance/index.html +1 -1
  14. package/examples/Phone Sensor Examples/touch/05_touch_angle/index.html +1 -1
  15. package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/README.md +51 -0
  16. package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/index.html +28 -0
  17. package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/sketch.js +177 -0
  18. package/examples/Phone Sensor Examples - Minimal/microphone/01_mic_level/index.html +1 -1
  19. package/examples/Phone Sensor Examples - Minimal/movement/01_orientation_basic/index.html +1 -1
  20. package/examples/Phone Sensor Examples - Minimal/movement/02_rotational_velocity/index.html +1 -1
  21. package/examples/Phone Sensor Examples - Minimal/movement/03_acceleration/index.html +1 -1
  22. package/examples/Phone Sensor Examples - Minimal/sound/01_sound_basic/index.html +1 -1
  23. package/examples/Phone Sensor Examples - Minimal/sound/02_sound_amplitude/index.html +1 -1
  24. package/examples/Phone Sensor Examples - Minimal/touch/01_touch_basic/index.html +1 -1
  25. package/examples/Phone Sensor Examples - Minimal/touch/02_touch_zones/index.html +1 -1
  26. package/examples/Phone Sensor Examples - Minimal/touch/03_touch_count/index.html +1 -1
  27. package/examples/Phone Sensor Examples - Minimal/touch/04_touch_distance/index.html +1 -1
  28. package/examples/Phone Sensor Examples - Minimal/touch/05_touch_angle/index.html +1 -1
  29. package/examples/Phone Sensor Examples - Minimal/vibration/01_haptic_feedback/index.html +18 -0
  30. package/examples/Phone Sensor Examples - Minimal/vibration/01_haptic_feedback/sketch.js +87 -0
  31. package/examples/Phone and Gif/collision/index.html +1 -1
  32. package/examples/Phone and Gif/fetch/index.html +1 -1
  33. package/examples/Phone and Gif/fly/index.html +1 -1
  34. package/examples/Phone and Gif/roll/index.html +1 -1
  35. package/examples/UXcompare/button-vs-movement/index.html +1 -1
  36. package/examples/UXcompare/button-vs-orientation/index.html +1 -1
  37. package/examples/UXcompare/button-vs-shake/index.html +1 -1
  38. package/examples/UXcompare/gyroscope-demo/index.html +1 -1
  39. package/examples/UXcompare/microphone-demo/index.html +1 -1
  40. package/examples/UXcompare/slider-vs-angle/index.html +1 -1
  41. package/examples/UXcompare/slider-vs-distance/index.html +1 -1
  42. package/examples/UXcompare/slider-vs-microphone/index.html +1 -1
  43. package/examples/UXcompare/slider-vs-touches/index.html +1 -1
  44. package/examples/UXcompare/sliders-vs-acceleration/index.html +1 -1
  45. package/examples/UXcompare/sliders-vs-rotation/index.html +1 -1
  46. package/examples/blankTemplate/index.html +1 -1
  47. package/examples/homepage/index.html +824 -88
  48. package/examples/workArea/01_camera-selector/README.md +119 -0
  49. package/examples/workArea/01_camera-selector/index.html +28 -0
  50. package/examples/workArea/01_camera-selector/sketch.js +239 -0
  51. package/examples/workArea/03_facemesh-nose/index.html +34 -0
  52. package/examples/workArea/03_facemesh-nose/sketch.js +247 -0
  53. package/examples/workArea/03_facemesh-nose-preload/index.html +34 -0
  54. package/examples/workArea/03_facemesh-nose-preload/sketch.js +173 -0
  55. package/examples/workArea/04_facemesh-FINAL/README.md +85 -0
  56. package/examples/workArea/04_facemesh-FINAL/index.html +31 -0
  57. package/examples/workArea/04_facemesh-FINAL/sketch.js +240 -0
  58. package/examples/workArea/04_facemesh-simplified_temp/README.md +93 -0
  59. package/examples/workArea/04_facemesh-simplified_temp/index.html +31 -0
  60. package/examples/workArea/04_facemesh-simplified_temp/sketch.js +259 -0
  61. package/examples/workArea/05_handpose/extra.js +0 -0
  62. package/examples/workArea/05_handpose/index.html +31 -0
  63. package/examples/workArea/05_handpose/sketch.js +362 -0
  64. package/examples/workArea/05_handpose-preload/index.html +31 -0
  65. package/examples/workArea/05_handpose-preload/sketch.js +362 -0
  66. package/examples/workArea/06_bodypose-FINAL/index.html +31 -0
  67. package/examples/workArea/06_bodypose-FINAL/sketch.js +360 -0
  68. package/package.json +5 -5
  69. package/src/p5-phone.js +630 -2
  70. package/src/permissionMic.js +0 -240
  71. package/src/permissionsGesture.js +0 -213
  72. package/src/permissionsGyro.js +0 -246
package/README.md CHANGED
@@ -1,15 +1,14 @@
1
1
  # p5-phone
2
- ![P5Phone.png](P5Phone.png)
2
+ ![P5Phone.png](p5-phone.png)
3
+ *Illustration by [Angela Torchio](https://angelatorchio.com/)*
3
4
 
4
- **Simplified mobile hardware access for p5.js** - handle sensors, microphone, touch, and browser gestures with ease.
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.4.4/dist/p5-phone.min.js"></script>
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.4.4/dist/p5-phone.js"></script> -->
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.4.4/dist/p5-phone.min.js"></script>
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.