p5-phone 1.8.0 → 1.9.1

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 (92) hide show
  1. package/README.md +165 -19
  2. package/dist/p5-phone.js +379 -3
  3. package/dist/p5-phone.min.js +1 -1
  4. package/examples/Phone Sensor Examples/microphone/01_mic_level/index.html +1 -1
  5. package/examples/Phone Sensor Examples/microphone/02_speech_recognition/index.html +1 -1
  6. package/examples/Phone Sensor Examples/movement/01_orientation_basic/index.html +1 -1
  7. package/examples/Phone Sensor Examples/movement/02_rotational_velocity/index.html +1 -1
  8. package/examples/Phone Sensor Examples/movement/03_acceleration/index.html +1 -1
  9. package/examples/Phone Sensor Examples/movement/04_device_shaken/index.html +23 -0
  10. package/examples/Phone Sensor Examples/movement/04_device_shaken/sketch.js +146 -0
  11. package/examples/Phone Sensor Examples/movement/05_device_moved/index.html +23 -0
  12. package/examples/Phone Sensor Examples/movement/05_device_moved/sketch.js +175 -0
  13. package/examples/Phone Sensor Examples/movement/06_device_orientation/index.html +23 -0
  14. package/examples/Phone Sensor Examples/movement/06_device_orientation/sketch.js +120 -0
  15. package/examples/Phone Sensor Examples/nfc/01_nfc_read/index.html +29 -0
  16. package/examples/Phone Sensor Examples/nfc/01_nfc_read/sketch.js +280 -0
  17. package/examples/Phone Sensor Examples/nfc/02_two_tag_effects/index.html +25 -0
  18. package/examples/Phone Sensor Examples/nfc/02_two_tag_effects/sketch.js +208 -0
  19. package/examples/Phone Sensor Examples/sound/01_dual_audio/index.html +1 -1
  20. package/examples/Phone Sensor Examples/sound/01_dual_audio/sketch.js +52 -54
  21. package/examples/Phone Sensor Examples/sound/02_volume_touches/index.html +1 -1
  22. package/examples/Phone Sensor Examples/sound/02_volume_touches/sketch.js +66 -67
  23. package/examples/Phone Sensor Examples/sound/03_motion_synth/index.html +24 -0
  24. package/examples/Phone Sensor Examples/sound/03_motion_synth/sketch.js +172 -0
  25. package/examples/Phone Sensor Examples/touch/01_touch_basic/index.html +1 -1
  26. package/examples/Phone Sensor Examples/touch/02_touch_zones/index.html +1 -1
  27. package/examples/Phone Sensor Examples/touch/03_touch_count/index.html +1 -1
  28. package/examples/Phone Sensor Examples/touch/04_touch_distance/index.html +1 -1
  29. package/examples/Phone Sensor Examples/touch/05_touch_angle/index.html +1 -1
  30. package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/index.html +1 -1
  31. package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/sketch.js +72 -74
  32. package/examples/Phone Sensor Examples - Minimal/microphone/01_mic_level/index.html +1 -1
  33. package/examples/Phone Sensor Examples - Minimal/movement/01_orientation_basic/index.html +1 -1
  34. package/examples/Phone Sensor Examples - Minimal/movement/02_rotational_velocity/index.html +1 -1
  35. package/examples/Phone Sensor Examples - Minimal/movement/03_acceleration/index.html +1 -1
  36. package/examples/Phone Sensor Examples - Minimal/movement/04_device_shaken/index.html +18 -0
  37. package/examples/Phone Sensor Examples - Minimal/movement/04_device_shaken/sketch.js +46 -0
  38. package/examples/Phone Sensor Examples - Minimal/movement/05_device_moved/index.html +18 -0
  39. package/examples/Phone Sensor Examples - Minimal/movement/05_device_moved/sketch.js +46 -0
  40. package/examples/Phone Sensor Examples - Minimal/movement/06_device_orientation/index.html +18 -0
  41. package/examples/Phone Sensor Examples - Minimal/movement/06_device_orientation/sketch.js +40 -0
  42. package/examples/Phone Sensor Examples - Minimal/sound/01_sound_basic/index.html +1 -1
  43. package/examples/Phone Sensor Examples - Minimal/sound/02_sound_amplitude/index.html +1 -1
  44. package/examples/Phone Sensor Examples - Minimal/sound/03_motion_synth/index.html +19 -0
  45. package/examples/Phone Sensor Examples - Minimal/sound/03_motion_synth/sketch.js +63 -0
  46. package/examples/Phone Sensor Examples - Minimal/touch/01_touch_basic/index.html +1 -1
  47. package/examples/Phone Sensor Examples - Minimal/touch/02_touch_zones/index.html +1 -1
  48. package/examples/Phone Sensor Examples - Minimal/touch/03_touch_count/index.html +1 -1
  49. package/examples/Phone Sensor Examples - Minimal/touch/04_touch_distance/index.html +1 -1
  50. package/examples/Phone Sensor Examples - Minimal/touch/05_touch_angle/index.html +1 -1
  51. package/examples/Phone Sensor Examples - Minimal/vibration/01_haptic_feedback/index.html +1 -1
  52. package/examples/Phone Sensor Examples - Minimal/vibration/01_haptic_feedback/sketch.js +45 -44
  53. package/examples/Phone and Gif/collision/index.html +1 -1
  54. package/examples/Phone and Gif/fetch/index.html +1 -1
  55. package/examples/Phone and Gif/fly/index.html +1 -1
  56. package/examples/Phone and Gif/roll/index.html +1 -1
  57. package/examples/UIStyles/canvas-style/sketch.js +13 -13
  58. package/examples/UIStyles/custom-element/sketch.js +19 -20
  59. package/examples/UXcompare/button-vs-movement/index.html +1 -1
  60. package/examples/UXcompare/button-vs-orientation/index.html +1 -1
  61. package/examples/UXcompare/button-vs-shake/index.html +1 -1
  62. package/examples/UXcompare/gyroscope-demo/index.html +1 -1
  63. package/examples/UXcompare/microphone-demo/index.html +1 -1
  64. package/examples/UXcompare/slider-vs-angle/index.html +1 -1
  65. package/examples/UXcompare/slider-vs-distance/index.html +1 -1
  66. package/examples/UXcompare/slider-vs-microphone/index.html +1 -1
  67. package/examples/UXcompare/slider-vs-touches/index.html +1 -1
  68. package/examples/UXcompare/sliders-vs-acceleration/index.html +1 -1
  69. package/examples/UXcompare/sliders-vs-rotation/index.html +1 -1
  70. package/examples/blankTemplate/index.html +1 -1
  71. package/examples/homepage/index.html +105 -6
  72. package/examples/homepage-v2/index.html +263 -0
  73. package/examples/homepage-v2/scripts/api-data.js +97 -0
  74. package/examples/homepage-v2/scripts/examples-data.js +463 -0
  75. package/examples/homepage-v2/scripts/navigation.js +45 -0
  76. package/examples/homepage-v2/scripts/render.js +214 -0
  77. package/examples/homepage-v2/styles/main.css +119 -0
  78. package/examples/ml5/Gaze_detector_class/GazeDetector.js +1 -1
  79. package/examples/ml5/Gaze_detector_class/README.md +1 -1
  80. package/examples/ml5/Gaze_detector_class/index.html +1 -1
  81. package/examples/ml5/PHONE_BodyPose_two_points/index.html +1 -1
  82. package/examples/ml5/PHONE_BodyPose_two_points/sketch.js +1 -1
  83. package/examples/ml5/PHONE_FaceMesh_two_points/index.html +1 -1
  84. package/examples/ml5/PHONE_FaceMesh_two_points/sketch.js +1 -1
  85. package/examples/ml5/PHONE_HandPose_two_points/index.html +1 -1
  86. package/examples/ml5/PHONE_HandPose_two_points/sketch.js +1 -1
  87. package/examples/ml5/PHONE_ObjectDetection/index.html +27 -0
  88. package/examples/ml5/PHONE_ObjectDetection/sketch.js +236 -0
  89. package/examples/ml5/THREE_FaceMesh_two_points/sketch.js +1 -1
  90. package/examples/ml5/THREE_HandPose_two_points/sketch.js +1 -1
  91. package/package.json +1 -1
  92. package/src/p5-phone.js +379 -3
package/README.md CHANGED
@@ -58,6 +58,7 @@ p5-phone supports both **p5.js 1.x** and **p5.js 2.0+**.
58
58
  | Microphone / Speech / Sound | ✅ | ✅ |
59
59
  | Camera (PhoneCamera) | ✅ | ✅ |
60
60
  | Vibration | ✅ | ✅ |
61
+ | NFC Tag Reading (Android only) | ✅ | ✅ |
61
62
  | Debug console | ✅ | ✅ |
62
63
  | lockGestures() | ✅ | ✅ |
63
64
  | `touchStarted()` / `touchEnded()` | ✅ | ❌ Use `mousePressed()` / `mouseReleased()` |
@@ -86,6 +87,7 @@ p5-phone automatically detects the p5.js version and adjusts its internal touch
86
87
  - [Speech Recognition Activation](#speech-recognition-activation)
87
88
  - [Combined Activation](#combined-activation)
88
89
  - [Vibration Motor (Android Only)](#vibration-motor-android-only)
90
+ - [NFC Tag Reading (Android Only)](#nfc-tag-reading-android-only)
89
91
  - [PhoneCamera (ML5 Integration)](#phonecamera-ml5-integration)
90
92
  - [Debug System](#debug-system)
91
93
  - [Permission UI Styles](#permission-ui-styles)
@@ -100,10 +102,10 @@ p5-phone automatically detects the p5.js version and adjusts its internal touch
100
102
 
101
103
  ```html
102
104
  <!-- Minified version (recommended) -->
103
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.8.0/dist/p5-phone.min.js"></script>
105
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.9.1/dist/p5-phone.min.js"></script>
104
106
 
105
107
  <!-- Development version (larger, with comments) -->
106
- <!-- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.8.0/dist/p5-phone.js"></script> -->
108
+ <!-- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.9.1/dist/p5-phone.js"></script> -->
107
109
  ```
108
110
 
109
111
  ### Basic Setup
@@ -132,7 +134,7 @@ p5-phone automatically detects the p5.js version and adjusts its internal touch
132
134
  <!-- For p5.js 2.0: <script src="https://cdn.jsdelivr.net/npm/p5@2/lib/p5.min.js"></script> -->
133
135
 
134
136
  <!-- Load p5-phone library -->
135
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.8.0/dist/p5-phone.min.js"></script>
137
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.9.1/dist/p5-phone.min.js"></script>
136
138
 
137
139
  </head>
138
140
  <body>
@@ -302,6 +304,9 @@ this.enableGyroTap('Tap to start');
302
304
  - `window.soundEnabled` - Boolean indicating if sound output is active
303
305
  - `window.speechEnabled` - Boolean indicating if speech recognition is active
304
306
  - `window.vibrationEnabled` - Boolean indicating if vibration is available (Android only)
307
+ - `window.nfcEnabled` - Boolean indicating if NFC scanning is active (Android only)
308
+ - `window.lastNfcSerialNumber` - Serial number string for the most recently read NFC tag
309
+ - `window.lastNfcAlias` - Alias string for the most recently read NFC tag, if one has been set
305
310
 
306
311
  **Usage:**
307
312
  ```javascript
@@ -326,14 +331,18 @@ function draw() {
326
331
  // Safe to use vibration (Android only)
327
332
  vibrate(50);
328
333
  }
334
+
335
+ if (window.nfcEnabled) {
336
+ // NFC scanning is active (Android only)
337
+ // Tag data arrives via nfcRead() callback
338
+ }
329
339
  }
330
340
 
331
341
  // You can also use them for conditional UI
332
- function setup() {
333
- enableGyroTap('Tap to enable motion');
334
-
335
- // Show different instructions based on status
336
- if (!window.sensorsEnabled) {
342
+ function draw() {
343
+ if (window.sensorsEnabled) {
344
+ debug("Motion sensors enabled");
345
+ } else {
337
346
  debug("Motion sensors not yet enabled");
338
347
  }
339
348
  }
@@ -638,6 +647,126 @@ function gameOver() {
638
647
  - Don't overuse - vibration can quickly drain battery
639
648
  - Test on Android devices as iOS doesn't support vibration
640
649
 
650
+ ### NFC Tag Reading (Android Only)
651
+
652
+ **Purpose:** Read NFC (Near Field Communication) tags using the Web NFC API. Ideal for interactive installations, scavenger hunts, or any sketch that responds to physical NFC tags.
653
+
654
+ **⚠️ Platform Support:**
655
+ - ✅ **Android** - Chrome 89+ and Samsung Internet 15+
656
+ - ❌ **iOS** - Not supported (Web NFC API not available on iOS)
657
+ - Requires **HTTPS** — NFC is blocked on insecure origins
658
+
659
+ **Important:** The Web NFC API requires user activation (a tap or click) before scanning can begin — the same pattern used by all other p5-phone permission functions. On unsupported devices/browsers, `window.nfcEnabled` will be `false` and calls will be safely ignored with console warnings.
660
+
661
+ **Commands:**
662
+ - `enableNfcTap(message)` - Tap anywhere on screen to enable NFC scanning
663
+ - `enableNfcButton(text)` - Creates a button with custom text to enable NFC
664
+ - `stopNfc()` - Stop NFC scanning
665
+ - `setNfcTagAlias(serialNumber, alias)` - Give a tag ID a human-friendly name
666
+ - `getNfcTagAlias(serialNumber)` - Get a saved alias for a tag ID
667
+ - `isNfcTag(aliasOrSerialNumber)` - Check whether the most recently read tag matches an alias or ID
668
+
669
+ **Status Variables:**
670
+ - `window.nfcEnabled` - Boolean indicating if NFC scanning is active
671
+ - `window.nfcStatus` - String describing NFC startup/read status
672
+ - `window.nfcError` - String containing the latest NFC startup/read error
673
+ - `window.nfcTagAliases` - Object mapping tag IDs to aliases
674
+ - `window.lastNfcMessage` - Object containing the most recently read tag's data
675
+ - `window.lastNfcSerialNumber` - Serial number string of the most recently read tag
676
+ - `window.lastNfcAlias` - Alias string for the most recently read tag, if one has been set
677
+
678
+ **Two-step workflow:**
679
+
680
+ 1. Open the NFC identifier example, scan each physical tag, type an alias, then download the tag list.
681
+ 2. Paste the generated `setNfcTagAlias()` lines into your sketch and use `isNfcTag()` in conditionals.
682
+
683
+ **User Callback:**
684
+
685
+ Define an `nfcRead()` function in your sketch to receive tag data when a tag is scanned:
686
+
687
+ ```javascript
688
+ function nfcRead(message, serialNumber) {
689
+ // message.serialNumber — tag serial number
690
+ // message.alias — saved alias, or '' if unnamed
691
+ // message.records — array of NDEF records, each with:
692
+ // .recordType — 'text', 'url', 'mime', etc.
693
+ // .data — decoded content (string for text/url, object for JSON, raw for others)
694
+ // .mediaType — MIME type (for 'mime' records)
695
+ // .id — record id (if present)
696
+ // .raw — original DataView
697
+ }
698
+ ```
699
+
700
+ **Usage:**
701
+ ```javascript
702
+ let tagText = 'No tag scanned yet';
703
+
704
+ function setup() {
705
+ createCanvas(windowWidth, windowHeight);
706
+ lockGestures();
707
+
708
+ // Paste IDs from the NFC identifier example.
709
+ setNfcTagAlias('04:85:2a:1b:9f:61:80', 'paintbrush');
710
+ setNfcTagAlias('04:42:18:3c:9f:61:80', 'desk');
711
+
712
+ enableNfcTap('Tap to enable NFC');
713
+ }
714
+
715
+ function draw() {
716
+ background(220);
717
+ textAlign(CENTER, CENTER);
718
+ textSize(20);
719
+
720
+ if (window.nfcEnabled) {
721
+ if (isNfcTag('paintbrush')) {
722
+ background(120, 220, 160);
723
+ text('Paintbrush tag read', width / 2, height / 2);
724
+ } else if (isNfcTag('desk')) {
725
+ background(140, 180, 240);
726
+ text('Desk tag read', width / 2, height / 2);
727
+ } else {
728
+ text(tagText, width / 2, height / 2);
729
+ text('Hold an NFC tag near your phone', width / 2, height / 2 + 40);
730
+ }
731
+ } else {
732
+ text('NFC not active', width / 2, height / 2);
733
+ }
734
+ }
735
+
736
+ function nfcRead(message, serialNumber) {
737
+ tagText = 'Tag: ' + (message.alias || serialNumber);
738
+
739
+ if (isNfcTag('paintbrush', serialNumber)) {
740
+ // This runs once when the paintbrush tag is scanned.
741
+ }
742
+
743
+ for (let record of message.records) {
744
+ if (record.recordType === 'text' || record.recordType === 'url') {
745
+ tagText += '\n' + record.data;
746
+ }
747
+ }
748
+ }
749
+ ```
750
+
751
+ **Record Types:**
752
+
753
+ NFC tags contain NDEF records. The most common types are:
754
+
755
+ | Record Type | `record.data` Contains | Example |
756
+ |-------------|----------------------|----------|
757
+ | `text` | Decoded string | `"Hello World"` |
758
+ | `url` | Decoded URL string | `"https://example.com"` |
759
+ | `mime` | Decoded string or parsed JSON | `{ id: 42 }` |
760
+ | other | Raw `DataView` | Binary data |
761
+
762
+ **Best Practices:**
763
+ - Always check `window.nfcEnabled` before relying on NFC features
764
+ - Use the `nfcRead()` callback for real-time tag processing
765
+ - Use `setNfcTagAlias()` and `isNfcTag()` when a sketch should respond to named physical objects
766
+ - Use `window.lastNfcMessage` in `draw()` for displaying the most recent tag
767
+ - Test on Android devices with Chrome — NFC is not available on iOS or desktop browsers
768
+ - Tags must be NDEF-formatted to be read by the Web NFC API
769
+
641
770
  ### Speech Recognition Activation
642
771
 
643
772
  **Purpose:** Enable the Web Speech API for voice input and speech-to-text in mobile browsers.
@@ -714,10 +843,10 @@ function draw() {
714
843
 
715
844
  ### PhoneCamera (ML5 Integration)
716
845
 
717
- **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.
846
+ **Purpose:** Simplified camera access optimized for ML5.js machine learning models (FaceMesh, HandPose, BodyPose, ObjectDetection, etc.). Handles camera initialization, coordinate mapping, mirroring, and display modes automatically.
718
847
 
719
848
  **Key Features:**
720
- - **Automatic Coordinate Mapping** - ML5 keypoints automatically mapped to canvas coordinates
849
+ - **Automatic Coordinate Mapping** - ML5 keypoints and bounding boxes automatically mapped to canvas coordinates
721
850
  - **Mirror Support** - Handles front camera mirroring for natural interaction
722
851
  - **Display Modes** - Multiple video sizing options (fitHeight, cover, contain, fixed)
723
852
  - **ML5 Optimized** - Direct integration with ML5 v1.x models
@@ -732,6 +861,8 @@ function draw() {
732
861
  | `cam.onReady(callback)` | Execute code when camera ready | Callback function |
733
862
  | `cam.mapKeypoint(keypoint)` | Map single ML5 keypoint to screen | ML5 keypoint object |
734
863
  | `cam.mapKeypoints(keypoints)` | Map array of ML5 keypoints | Array of ML5 keypoints |
864
+ | `cam.mapBox(box)` | Map single ML5 bounding box to screen | ML5 detection object with x, y, width, height |
865
+ | `cam.mapBoxes(boxes)` | Map array of ML5 bounding boxes | Array of ML5 detection objects |
735
866
 
736
867
  **Properties:**
737
868
 
@@ -765,7 +896,7 @@ function setup() {
765
896
  let options = {
766
897
  maxFaces: 1,
767
898
  refineLandmarks: false,
768
- flipHorizontal: false // cam.mapKeypoint() handles mirroring
899
+ flipped: false // cam.mapKeypoint() handles mirroring
769
900
  };
770
901
 
771
902
  facemesh = ml5.faceMesh(options, modelLoaded);
@@ -818,7 +949,7 @@ function draw() {
818
949
 
819
950
  **Coordinate Mapping:**
820
951
 
821
- The `mapKeypoint()` and `mapKeypoints()` functions automatically handle:
952
+ The `mapKeypoint()`, `mapKeypoints()`, `mapBox()`, and `mapBoxes()` functions automatically handle:
822
953
  - Video-to-canvas scaling
823
954
  - Mirror transformation (for front camera)
824
955
  - Offset positioning (for different display modes)
@@ -834,26 +965,34 @@ let hands = cam.mapKeypoints(hand.keypoints);
834
965
  hands.forEach(point => {
835
966
  circle(point.x, point.y, 5);
836
967
  });
968
+
969
+ // Object detection bounding box
970
+ let mappedObject = cam.mapBox(detection);
971
+ rect(mappedObject.x, mappedObject.y, mappedObject.width, mappedObject.height);
837
972
  ```
838
973
 
839
974
  **ML5 Model Examples:**
840
975
 
841
976
  ```javascript
842
977
  // FaceMesh (468 keypoints)
843
- let options = { maxFaces: 1, refineLandmarks: false, flipHorizontal: false };
978
+ let options = { maxFaces: 1, refineLandmarks: false, flipped: false };
844
979
  facemesh = ml5.faceMesh(options, modelLoaded);
845
980
 
846
981
  // HandPose (21 keypoints per hand)
847
- let options = { maxHands: 2, runtime: 'mediapipe', flipHorizontal: false };
982
+ let options = { maxHands: 2, runtime: 'mediapipe', flipped: false };
848
983
  handpose = ml5.handPose(options, modelLoaded);
849
984
 
850
985
  // BodyPose (33 keypoints with 3D)
851
986
  let options = { modelType: 'MULTIPOSE_LIGHTNING', flipped: false };
852
987
  bodypose = ml5.bodyPose('BlazePose', options, modelLoaded);
988
+
989
+ // ObjectDetection (bounding boxes)
990
+ objectDetector = await ml5.objectDetection('cocossd');
991
+ objectDetector.detectStart(cam.videoElement, gotDetections);
853
992
  ```
854
993
 
855
994
  **Important Notes:**
856
- - Always set `flipHorizontal: false` in ML5 options (PhoneCamera handles mirroring)
995
+ - Always set `flipped: false` in ML5 options when available (PhoneCamera handles mirroring)
857
996
  - Use `cam.videoElement` (native HTML video element) when passing to ML5's `detectStart()`
858
997
  - Check `cam.ready` before using video or drawing keypoints
859
998
  - Call `enableCameraTap()` to handle camera permissions automatically
@@ -924,6 +1063,7 @@ The canvas displays a centered message until the user taps. Great for "full-scre
924
1063
  - `enableSensorCanvas(message)`
925
1064
  - `enableMicCanvas(message)`
926
1065
  - `enableSpeechCanvas(message)`
1066
+ - `enableNfcCanvas(message)`
927
1067
  - `enableAllCanvas(message)`
928
1068
  - `enableCameraCanvas(message)`
929
1069
 
@@ -936,9 +1076,11 @@ function setup() {
936
1076
  }
937
1077
 
938
1078
  function draw() {
939
- if (!window.sensorsEnabled) return;
940
1079
  background(220);
941
- circle(width/2 + rotationY * 3, height/2 + rotationX * 3, 50);
1080
+
1081
+ if (window.sensorsEnabled) {
1082
+ circle(width/2 + rotationY * 3, height/2 + rotationX * 3, 50);
1083
+ }
942
1084
  }
943
1085
  ```
944
1086
 
@@ -950,6 +1092,7 @@ A styled banner slides in from the top of the screen with an animated entrance.
950
1092
  - `enableSensorBanner(message)`
951
1093
  - `enableMicBanner(message)`
952
1094
  - `enableSpeechBanner(message)`
1095
+ - `enableNfcBanner(message)`
953
1096
  - `enableAllBanner(message)`
954
1097
  - `enableCameraBanner(message)`
955
1098
 
@@ -977,6 +1120,7 @@ Bind the permission activation to any existing HTML element on the page using a
977
1120
  - `enableSensorOn(selector)`
978
1121
  - `enableMicOn(selector)`
979
1122
  - `enableSpeechOn(selector)`
1123
+ - `enableNfcOn(selector)`
980
1124
  - `enableAllOn(selector)`
981
1125
  - `enableCameraOn(selector)`
982
1126
 
@@ -996,9 +1140,11 @@ function setup() {
996
1140
  }
997
1141
 
998
1142
  function draw() {
999
- if (!window.sensorsEnabled) return;
1000
1143
  background(220);
1001
- circle(width/2 + rotationY * 3, height/2 + rotationX * 3, 50);
1144
+
1145
+ if (window.sensorsEnabled) {
1146
+ circle(width/2 + rotationY * 3, height/2 + rotationX * 3, 50);
1147
+ }
1002
1148
  }
1003
1149
  ```
1004
1150