p5-phone 1.4.4
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/LICENSE +21 -0
- package/README.md +509 -0
- package/dist/p5-phone.js +1062 -0
- package/dist/p5-phone.min.js +10 -0
- package/examples/Phone Sensor Examples/microphone/01_mic_level/index.html +19 -0
- package/examples/Phone Sensor Examples/microphone/01_mic_level/sketch.js +117 -0
- package/examples/Phone Sensor Examples/movement/01_orientation_basic/index.html +28 -0
- package/examples/Phone Sensor Examples/movement/01_orientation_basic/sketch.js +123 -0
- package/examples/Phone Sensor Examples/movement/02_rotational_velocity/index.html +28 -0
- package/examples/Phone Sensor Examples/movement/02_rotational_velocity/sketch.js +144 -0
- package/examples/Phone Sensor Examples/movement/03_acceleration/index.html +28 -0
- package/examples/Phone Sensor Examples/movement/03_acceleration/sketch.js +87 -0
- package/examples/Phone Sensor Examples/sound/01_dual_audio/index.html +31 -0
- package/examples/Phone Sensor Examples/sound/01_dual_audio/sketch.js +225 -0
- package/examples/Phone Sensor Examples/sound/01_dual_audio/tracks/audio1.mp3 +0 -0
- package/examples/Phone Sensor Examples/sound/01_dual_audio/tracks/audio2.mp3 +0 -0
- package/examples/Phone Sensor Examples/sound/02_volume_touches/index.html +31 -0
- package/examples/Phone Sensor Examples/sound/02_volume_touches/sketch.js +269 -0
- package/examples/Phone Sensor Examples/sound/02_volume_touches/tracks/audio1.mp3 +0 -0
- package/examples/Phone Sensor Examples/touch/01_touch_basic/index.html +28 -0
- package/examples/Phone Sensor Examples/touch/01_touch_basic/sketch.js +94 -0
- package/examples/Phone Sensor Examples/touch/02_touch_zones/index.html +28 -0
- package/examples/Phone Sensor Examples/touch/02_touch_zones/sketch.js +220 -0
- package/examples/Phone Sensor Examples/touch/03_touch_count/index.html +28 -0
- package/examples/Phone Sensor Examples/touch/03_touch_count/sketch.js +93 -0
- package/examples/Phone Sensor Examples/touch/04_touch_distance/index.html +28 -0
- package/examples/Phone Sensor Examples/touch/04_touch_distance/sketch.js +120 -0
- package/examples/Phone Sensor Examples/touch/05_touch_angle/index.html +28 -0
- package/examples/Phone Sensor Examples/touch/05_touch_angle/sketch.js +117 -0
- package/examples/Phone Sensor Examples - Minimal/microphone/01_mic_level/index.html +19 -0
- package/examples/Phone Sensor Examples - Minimal/microphone/01_mic_level/sketch.js +72 -0
- package/examples/Phone Sensor Examples - Minimal/movement/01_orientation_basic/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/movement/01_orientation_basic/sketch.js +51 -0
- package/examples/Phone Sensor Examples - Minimal/movement/02_rotational_velocity/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/movement/02_rotational_velocity/sketch.js +70 -0
- package/examples/Phone Sensor Examples - Minimal/movement/03_acceleration/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/movement/03_acceleration/sketch.js +83 -0
- package/examples/Phone Sensor Examples - Minimal/sound/01_sound_basic/index.html +19 -0
- package/examples/Phone Sensor Examples - Minimal/sound/01_sound_basic/sketch.js +96 -0
- package/examples/Phone Sensor Examples - Minimal/sound/01_sound_basic/tracks/audio1.mp3 +0 -0
- package/examples/Phone Sensor Examples - Minimal/sound/02_sound_amplitude/index.html +19 -0
- package/examples/Phone Sensor Examples - Minimal/sound/02_sound_amplitude/sketch.js +118 -0
- package/examples/Phone Sensor Examples - Minimal/sound/02_sound_amplitude/tracks/audio1.mp3 +0 -0
- package/examples/Phone Sensor Examples - Minimal/touch/01_touch_basic/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/touch/01_touch_basic/sketch.js +58 -0
- package/examples/Phone Sensor Examples - Minimal/touch/02_touch_zones/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/touch/02_touch_zones/sketch.js +78 -0
- package/examples/Phone Sensor Examples - Minimal/touch/03_touch_count/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/touch/03_touch_count/sketch.js +64 -0
- package/examples/Phone Sensor Examples - Minimal/touch/04_touch_distance/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/touch/04_touch_distance/sketch.js +69 -0
- package/examples/Phone Sensor Examples - Minimal/touch/05_touch_angle/index.html +18 -0
- package/examples/Phone Sensor Examples - Minimal/touch/05_touch_angle/sketch.js +85 -0
- package/examples/Phone and Gif/collision/README.md +31 -0
- Gif/collision/gifs/spaceSuit2.png +0 -0
- package/examples/Phone and Gif/collision/index.html +19 -0
- package/examples/Phone and Gif/collision/sketch.js +226 -0
- Gif/fetch/gifs/corgiswimflip.gif +0 -0
- package/examples/Phone and Gif/fetch/index.html +18 -0
- package/examples/Phone and Gif/fetch/sketch.js +139 -0
- Gif/fly/gifs/comparison.gif +0 -0
- package/examples/Phone and Gif/fly/index.html +18 -0
- package/examples/Phone and Gif/fly/sketch.js +103 -0
- Gif/roll/gifs/how-penciles-are-made.gif +0 -0
- package/examples/Phone and Gif/roll/index.html +18 -0
- package/examples/Phone and Gif/roll/sketch.js +121 -0
- package/examples/UXcompare/button-vs-movement/index.html +45 -0
- package/examples/UXcompare/button-vs-movement/sketch.js +355 -0
- package/examples/UXcompare/button-vs-orientation/index.html +25 -0
- package/examples/UXcompare/button-vs-orientation/sketch.js +317 -0
- package/examples/UXcompare/button-vs-shake/index.html +45 -0
- package/examples/UXcompare/button-vs-shake/sketch.js +320 -0
- package/examples/UXcompare/gyroscope-demo/index.html +78 -0
- package/examples/UXcompare/gyroscope-demo/sketch.js +166 -0
- package/examples/UXcompare/index.html +419 -0
- package/examples/UXcompare/microphone-demo/index.html +79 -0
- package/examples/UXcompare/microphone-demo/sketch.js +210 -0
- package/examples/UXcompare/slider-vs-angle/index.html +25 -0
- package/examples/UXcompare/slider-vs-angle/sketch.js +429 -0
- package/examples/UXcompare/slider-vs-distance/index.html +25 -0
- package/examples/UXcompare/slider-vs-distance/sketch.js +401 -0
- package/examples/UXcompare/slider-vs-microphone/index.html +26 -0
- package/examples/UXcompare/slider-vs-microphone/sketch.js +336 -0
- package/examples/UXcompare/slider-vs-touches/index.html +25 -0
- package/examples/UXcompare/slider-vs-touches/sketch.js +376 -0
- package/examples/UXcompare/sliders-vs-acceleration/index.html +25 -0
- package/examples/UXcompare/sliders-vs-acceleration/sketch.js +361 -0
- package/examples/UXcompare/sliders-vs-rotation/index.html +25 -0
- package/examples/UXcompare/sliders-vs-rotation/sketch.js +375 -0
- package/examples/blankTemplate/index.html +31 -0
- package/examples/blankTemplate/sketch.js +55 -0
- package/examples/homepage/index.html +506 -0
- package/package.json +73 -0
- package/src/p5-phone.js +1062 -0
- package/src/permissionMic.js +240 -0
- package/src/permissionsGesture.js +213 -0
- package/src/permissionsGyro.js +246 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* p5-phone v1.4.4
|
|
3
|
+
* Simplified mobile hardware access for p5.js - handle sensors, microphone, touch, and browser gestures with ease
|
|
4
|
+
* https://github.com/DigitalFuturesOCADU/p5-phone
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2025 Nick Puckett
|
|
7
|
+
* Released under the MIT License
|
|
8
|
+
* https://opensource.org/licenses/MIT
|
|
9
|
+
*/
|
|
10
|
+
window._originalConsoleError=console.error,window._originalConsoleWarn=console.warn,window._debugErrorHandlersSet||(window._debugErrorHandlersSet=!0,window._earlyErrors=window._earlyErrors||[],window.addEventListener("error",function(e){const n=`${e.error?.message||e.message||"Unknown error"} (${e.filename?e.filename.split("/").pop():"unknown file"}:${e.lineno||"unknown line"})`;console.error("🚨 Error caught:",n),e.error?.stack&&console.error("Stack:",e.error.stack),window._earlyErrors.push({type:"error",message:"JavaScript Error: "+n,stack:e.error?.stack}),!1===window.SHOW_DEBUG||window._debugVisible||"function"==typeof showDebug&&showDebug(),window._debugVisible&&"function"==typeof debugError&&(debugError("JavaScript Error:",n),e.error?.stack&&debugError("Stack trace:",e.error.stack))}),window.addEventListener("unhandledrejection",function(e){const n=e.reason?.message||e.reason||"Unknown promise rejection";console.error("🚨 Promise rejection caught:",n),window._earlyErrors.push({type:"error",message:"Unhandled Promise Rejection: "+n}),window._debugVisible&&"function"==typeof debugError&&debugError("Unhandled Promise Rejection:",n)})),window.sensorsEnabled=!1,window.micEnabled=!1,window.soundEnabled=!1,window.gesturesLocked=!1;let _permissionsInitialized=!1,_micInstance=null;function lockGestures(){window.gesturesLocked||(console.log("🔒 Locking mobile gestures..."),_initializeGestureBlocking(),_initializeP5TouchOverrides(),window.gesturesLocked=!0,console.log("✅ Mobile gestures locked"))}function enableGyroButton(e="ENABLE MOTION SENSORS",n="Requesting motion sensors..."){_createPermissionButton(e,n,async()=>{await _requestMotionPermissions(),console.log("✅ Gyroscope enabled via button")})}function enableGyroTap(e="Tap screen to enable motion sensors"){_createTapToEnable(e,async()=>{await _requestMotionPermissions(),console.log("✅ Gyroscope enabled via tap")})}function enableMicButton(e="ENABLE MICROPHONE",n="Requesting microphone access..."){_createPermissionButton(e,n,async()=>{await _requestMicrophonePermissions(),console.log("✅ Microphone enabled via button")})}function enableMicTap(e="Tap screen to enable microphone"){_createTapToEnable(e,async()=>{await _requestMicrophonePermissions(),console.log("✅ Microphone enabled via tap")})}function enableSoundButton(e="ENABLE SOUND",n="Enabling audio..."){_createPermissionButton(e,n,async()=>{await _requestSoundOutput(),console.log("✅ Sound output enabled via button")})}function enableSoundTap(e="Tap screen to enable sound"){_createTapToEnable(e,async()=>{await _requestSoundOutput(),console.log("✅ Sound output enabled via tap")})}function enableAllButton(e="ENABLE MOTION & MICROPHONE",n="Requesting permissions..."){_createPermissionButton(e,n,async()=>{await _requestMotionPermissions(),await _requestMicrophonePermissions(),console.log("✅ Motion sensors and microphone enabled via button")})}function enableAllTap(e="Tap screen to enable motion sensors & microphone"){_createTapToEnable(e,async()=>{await _requestMotionPermissions(),await _requestMicrophonePermissions(),console.log("✅ Motion sensors and microphone enabled via tap")})}async function _requestMotionPermissions(){try{if("undefined"!=typeof DeviceOrientationEvent&&"function"==typeof DeviceOrientationEvent.requestPermission){const e=await DeviceOrientationEvent.requestPermission();if(console.log("Orientation permission:",e),"undefined"!=typeof DeviceMotionEvent&&"function"==typeof DeviceMotionEvent.requestPermission){const e=await DeviceMotionEvent.requestPermission();console.log("Motion permission:",e)}}window.sensorsEnabled=!0,_notifySketchReady()}catch(e){console.error("Motion sensor permission error:",e),_debugVisible&&debugError("Motion sensor permission error:",e),window.sensorsEnabled=!0,_notifySketchReady()}}async function _requestMicrophonePermissions(){try{"undefined"!=typeof userStartAudio&&await userStartAudio(),"undefined"!=typeof mic&&mic&&mic.start?(mic.start(),_micInstance=mic,window.micEnabled=!0):console.warn("No microphone object found. Create one with: mic = new p5.AudioIn();"),_notifySketchReady()}catch(e){console.error("Microphone permission error:",e),_debugVisible&&debugError("Microphone permission error:",e),_notifySketchReady()}}async function _requestSoundOutput(){try{"undefined"!=typeof userStartAudio&&await userStartAudio(),window.soundEnabled=!0,_notifySketchReady()}catch(e){console.error("Sound output error:",e),_debugVisible&&debugError("Sound output error:",e),window.soundEnabled=!0,_notifySketchReady()}}function _notifySketchReady(){"function"==typeof userSetupComplete&&userSetupComplete(),window.dispatchEvent(new CustomEvent("permissionsReady",{detail:{sensors:window.sensorsEnabled,microphone:window.micEnabled,sound:window.soundEnabled,gestures:window.gesturesLocked}}))}function _createPermissionButton(e,n,o){_removeExistingUI();const t=document.createElement("button");t.id="permissionButton",t.textContent=e,t.style.cssText="\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 20px 40px;\n font-size: 18px;\n font-weight: bold;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n border-radius: 12px;\n cursor: pointer;\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n box-shadow: 0 4px 15px rgba(0,0,0,0.2);\n transition: transform 0.2s ease;\n touch-action: manipulation;\n ";const i=document.createElement("div");i.id="permissionStatus",i.textContent=n,i.style.cssText="\n position: fixed;\n top: 60%;\n left: 50%;\n transform: translate(-50%, 0);\n color: white;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n z-index: 999998;\n display: none;\n ",t.addEventListener("mouseenter",()=>{t.style.transform="translate(-50%, -50%) scale(1.05)"}),t.addEventListener("mouseleave",()=>{t.style.transform="translate(-50%, -50%) scale(1)"});const r=async()=>{t.parentNode&&(t.style.display="none",i.style.display="block",await o(),i.style.display="none",_removeExistingUI())};t.addEventListener("click",r),t.addEventListener("touchend",function(e){e.preventDefault(),e.stopPropagation(),r()}),t.addEventListener("pointerup",function(e){e.preventDefault(),e.stopPropagation(),r()}),document.body.appendChild(t),document.body.appendChild(i)}function _createTapToEnable(e,n){_removeExistingUI();const o=document.createElement("div");o.id="tapOverlay",o.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n cursor: pointer;\n touch-action: manipulation;\n ";const t=document.createElement("div");t.textContent=e,t.style.cssText="\n color: white;\n font-size: 24px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n padding: 40px;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 12px;\n background: rgba(255, 255, 255, 0.1);\n backdrop-filter: blur(10px);\n ",o.appendChild(t);const i=async()=>{o.parentNode&&(t.textContent="Enabling...",await n(),o.parentNode&&document.body.removeChild(o))};o.addEventListener("click",i),o.addEventListener("touchend",function(e){e.preventDefault(),e.stopPropagation(),i()}),o.addEventListener("pointerup",function(e){e.preventDefault(),e.stopPropagation(),i()}),document.body.appendChild(o)}function _removeExistingUI(){const e=document.getElementById("permissionButton"),n=document.getElementById("permissionStatus"),o=document.getElementById("tapOverlay");e&&e.remove(),n&&n.remove(),o&&o.remove()}function _initializeGestureBlocking(){window.history.pushState(null,"",window.location.href),window.onpopstate=function(){window.history.pushState(null,"",window.location.href)},window.addEventListener("beforeunload",function(e){e.preventDefault(),e.returnValue=""}),_initializeEdgeSwipePrevention(),_initializeOtherGesturePrevention()}function _initializeEdgeSwipePrevention(){let e=0,n=0;document.addEventListener("touchstart",function(o){o.touches&&o.touches.length>0&&(e=o.touches[0].clientX,n=o.touches[0].clientY,(e<20||e>window.innerWidth-20)&&o.preventDefault())},{passive:!1,capture:!0}),document.addEventListener("touchmove",function(o){if(!o.touches||0===o.touches.length)return;let t=o.touches[0].clientX,i=o.touches[0].clientY,r=t-e,s=i-n;(e<20&&r>0||e>window.innerWidth-20&&r<0)&&(o.preventDefault(),o.stopPropagation()),0===window.pageYOffset&&s>0&&o.preventDefault(),!o.target||"CANVAS"!==o.target.tagName||document.getElementById("tapOverlay")||document.getElementById("permissionButton")||o.preventDefault()},{passive:!1,capture:!0})}function _initializeOtherGesturePrevention(){document.addEventListener("gesturestart",function(e){e.preventDefault()}),document.addEventListener("gesturechange",function(e){e.preventDefault()}),document.addEventListener("gestureend",function(e){e.preventDefault()});let e=0;document.addEventListener("touchend",function(n){if(n.target&&("tapOverlay"===n.target.id||n.target.closest("#tapOverlay")||"permissionButton"===n.target.id||"permissionStatus"===n.target.id||n.target.closest("#permissionButton")||n.target.closest("#permissionStatus")))return;const o=Date.now();o-e<=300&&n.preventDefault(),e=o},!1),window.oncontextmenu=function(e){return e.preventDefault(),e.stopPropagation(),!1}}function _initializeP5TouchOverrides(){setTimeout(()=>{if(window._setupDone)_overrideP5Touch();else{const e=setInterval(()=>{window._setupDone&&(_overrideP5Touch(),clearInterval(e))},100)}},100)}function _overrideP5Touch(){const e=window.touchStarted||function(){},n=window.touchMoved||function(){},o=window.touchEnded||function(){},t=window.mousePressed||function(){},i=window.mouseDragged||function(){},r=window.mouseReleased||function(){};window.touchStarted=function(n){return e(n),!1},window.touchMoved=function(e){return n(e),!1},window.touchEnded=function(e){return o(e),!1},window.mousePressed=function(e){return t(e),!1},window.mouseDragged=function(e){return i(e),!1},window.mouseReleased=function(e){return r(e),!1}}document.addEventListener("DOMContentLoaded",function(){const e=document.getElementById("startButton"),n=document.getElementById("statusText");e&&n&&(console.warn("⚠️ Legacy HTML elements detected. Consider using the new API functions instead."),e.addEventListener("click",async()=>{e.classList.add("hidden"),n.classList.remove("hidden"),n.textContent="Requesting permissions...",await _requestMotionPermissions(),await _requestMicrophonePermissions(),n.classList.add("hidden")}),lockGestures())});let _debugPanel=null,_debugVisible=!1,_debugMessages=[];const MAX_DEBUG_MESSAGES=20;function showDebug(){_createDebugPanel(),_debugPanel.style.display="block",_debugVisible=!0,window._debugVisible=!0,_setupConsoleOverrides(),_displayEarlyErrors()}function hideDebug(){_debugPanel&&(_debugPanel.style.display="none",_debugVisible=!1)}function toggleDebug(){_debugVisible?hideDebug():showDebug()}function debug(...e){console.log(...e);_addDebugMessage(e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" "),"log")}function debugError(...e){(window._originalConsoleError||console.error).apply(console,e);_addDebugMessage(`❌ ERROR: ${e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" ")}`,"error")}function debugWarn(...e){(window._originalConsoleWarn||console.warn).apply(console,e);_addDebugMessage(`⚠️ WARNING: ${e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" ")}`,"warning")}function _addDebugMessage(e,n="log"){const o={text:`[${(new Date).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3})}] ${e}`,type:n};_debugMessages.push(o),_debugMessages.length>20&&_debugMessages.shift(),_debugPanel&&_updateDebugDisplay()}function _setupConsoleOverrides(){window._consoleOverrideSet||(window._consoleOverrideSet=!0,window._originalConsoleError=console.error,window._originalConsoleWarn=console.warn,console.error=function(...e){window._originalConsoleError.apply(console,e),_debugVisible&&debugError(...e)},console.warn=function(...e){window._originalConsoleWarn.apply(console,e),_debugVisible&&debugWarn(...e)})}function _displayEarlyErrors(){window._earlyErrors&&window._earlyErrors.length>0&&(debugError(`🚨 Found ${window._earlyErrors.length} early error(s):`),window._earlyErrors.forEach(e=>{debugError(e.message),e.stack&&debugError("Stack trace:",e.stack)}),window._earlyErrors=[])}function _createDebugPanel(){if(_debugPanel)return;_debugPanel=document.createElement("div"),_debugPanel.id="mobile-debug-panel",_debugPanel.innerHTML='\n <div id="mobile-debug-header">\n <span>Debug</span>\n <button id="mobile-debug-close">×</button>\n </div>\n <div id="mobile-debug-content"></div>\n ';const e=document.createElement("style");e.textContent="\n #mobile-debug-panel {\n position: fixed;\n top: 20px;\n right: 20px;\n width: 350px;\n max-width: calc(100vw - 40px);\n max-height: 400px;\n background: rgba(0, 0, 0, 0.9);\n color: #ffffff;\n font-family: 'Courier New', monospace;\n font-size: 12px;\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n z-index: 10000;\n display: none;\n }\n \n #mobile-debug-header {\n background: rgba(255, 255, 255, 0.1);\n padding: 8px 12px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-radius: 8px 8px 0 0;\n }\n \n #mobile-debug-header span {\n font-weight: bold;\n font-size: 13px;\n }\n \n #mobile-debug-close {\n background: none;\n border: none;\n color: #ffffff;\n font-size: 18px;\n cursor: pointer;\n padding: 0;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n #mobile-debug-close:hover {\n background: rgba(255, 255, 255, 0.1);\n border-radius: 4px;\n }\n \n #mobile-debug-content {\n padding: 12px;\n max-height: 340px;\n overflow-y: auto;\n word-wrap: break-word;\n line-height: 1.4;\n }\n \n .debug-message {\n margin-bottom: 4px;\n white-space: pre-wrap;\n }\n \n .debug-message.error {\n color: #ff6b6b;\n background: rgba(255, 107, 107, 0.1);\n padding: 4px;\n border-radius: 3px;\n border-left: 3px solid #ff6b6b;\n }\n \n .debug-message.warning {\n color: #ffd93d;\n background: rgba(255, 217, 61, 0.1);\n padding: 4px;\n border-radius: 3px;\n border-left: 3px solid #ffd93d;\n }\n \n .debug-timestamp {\n color: #888;\n font-size: 10px;\n }\n \n @media (max-width: 480px) {\n #mobile-debug-panel {\n width: calc(100vw - 20px);\n right: 10px;\n top: 10px;\n }\n }\n ",document.head.appendChild(e),document.body.appendChild(_debugPanel),document.getElementById("mobile-debug-close").onclick=hideDebug,_updateDebugDisplay()}function _updateDebugDisplay(){if(!_debugPanel)return;const e=document.getElementById("mobile-debug-content");e&&(e.innerHTML=_debugMessages.map(e=>"string"==typeof e?`<div class="debug-message">${e}</div>`:`<div class="debug-message ${e.type}">${e.text}</div>`).join(""),e.scrollTop=e.scrollHeight)}debug.clear=function(){_debugMessages=[],_debugPanel&&_updateDebugDisplay(),console.clear()},window.debug=debug,window.debugError=debugError,window.debugWarn=debugWarn,window.showDebug=showDebug,window.hideDebug=hideDebug,window.toggleDebug=toggleDebug,window.lockGestures=lockGestures,window.enableGyroTap=enableGyroTap,window.enableGyroButton=enableGyroButton,window.enableMicTap=enableMicTap,window.enableMicButton=enableMicButton,window.enableSoundTap=enableSoundTap,window.enableSoundButton=enableSoundButton,window.enableAllTap=enableAllTap,window.enableAllButton=enableAllButton,"undefined"!=typeof p5&&p5.prototype&&(p5.prototype.lockGestures=lockGestures,p5.prototype.enableGyroTap=enableGyroTap,p5.prototype.enableGyroButton=enableGyroButton,p5.prototype.enableMicTap=enableMicTap,p5.prototype.enableMicButton=enableMicButton,p5.prototype.enableSoundTap=enableSoundTap,p5.prototype.enableSoundButton=enableSoundButton,p5.prototype.enableAllTap=enableAllTap,p5.prototype.enableAllButton=enableAllButton,p5.prototype.showDebug=showDebug,p5.prototype.hideDebug=hideDebug,p5.prototype.toggleDebug=toggleDebug,p5.prototype.debug=debug,p5.prototype.debugError=debugError,p5.prototype.debugWarn=debugWarn,console.log("✅ Mobile p5.js Permissions: p5.prototype functions registered"));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>P5.js Mobile - Microphone Level</title>
|
|
5
|
+
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
|
|
6
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/addons/p5.sound.min.js"></script>
|
|
7
|
+
<script src="https://cdn.jsdelivr.net/npm/mobile-p5-permissions@1.4.4/dist/p5.mobile-permissions.min.js"></script>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
}
|
|
14
|
+
</style>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<script src="sketch.js"></script>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Microphone level example
|
|
2
|
+
// Demonstrates reading microphone input level with visual feedback
|
|
3
|
+
// Shows text display and full-width bar graph with threshold detection
|
|
4
|
+
|
|
5
|
+
// Global variables - easy to adjust for different use cases
|
|
6
|
+
let mic;
|
|
7
|
+
let micLevel = 0;
|
|
8
|
+
let micMultiplier = 5; // Multiplier to amplify mic sensitivity
|
|
9
|
+
let threshold = 0.3; // Threshold for background color change (0.0 - 1.0)
|
|
10
|
+
let backgroundColor;
|
|
11
|
+
let backgroundColorQuiet;
|
|
12
|
+
let backgroundColorLoud;
|
|
13
|
+
|
|
14
|
+
function setup()
|
|
15
|
+
{
|
|
16
|
+
createCanvas(windowWidth, windowHeight);
|
|
17
|
+
|
|
18
|
+
// Set up colors
|
|
19
|
+
backgroundColorQuiet = color(50, 50, 50); // Dark gray when quiet
|
|
20
|
+
backgroundColorLoud = color(255, 100, 50); // Orange when loud
|
|
21
|
+
backgroundColor = backgroundColorQuiet;
|
|
22
|
+
|
|
23
|
+
// Create microphone input (global variable for library to use)
|
|
24
|
+
mic = new p5.AudioIn();
|
|
25
|
+
|
|
26
|
+
textAlign(CENTER, CENTER);
|
|
27
|
+
textSize(16);
|
|
28
|
+
|
|
29
|
+
// lock Gesturs
|
|
30
|
+
lockGestures();
|
|
31
|
+
|
|
32
|
+
// Request permission for microphone on iOS
|
|
33
|
+
enableMicTap();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function draw()
|
|
37
|
+
{
|
|
38
|
+
background(backgroundColor);
|
|
39
|
+
|
|
40
|
+
// Check if microphone is available
|
|
41
|
+
if (window.micEnabled)
|
|
42
|
+
{
|
|
43
|
+
// Get current microphone level (0.0 to 1.0) and apply multiplier
|
|
44
|
+
micLevel = mic.getLevel() * micMultiplier;
|
|
45
|
+
|
|
46
|
+
// Check if level exceeds threshold and change background
|
|
47
|
+
if (micLevel > threshold)
|
|
48
|
+
{
|
|
49
|
+
backgroundColor = backgroundColorLoud;
|
|
50
|
+
}
|
|
51
|
+
else
|
|
52
|
+
{
|
|
53
|
+
backgroundColor = backgroundColorQuiet;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Display microphone level as text
|
|
57
|
+
fill(255);
|
|
58
|
+
text("Microphone Level", width/2, height/6);
|
|
59
|
+
|
|
60
|
+
// Display numeric value with more precision
|
|
61
|
+
text("Level: " + nf(micLevel, 1, 3), width/2, height/6 + 40);
|
|
62
|
+
|
|
63
|
+
// Display threshold value
|
|
64
|
+
fill(150);
|
|
65
|
+
text("Threshold: " + nf(threshold, 1, 2), width/2, height/6 + 70);
|
|
66
|
+
|
|
67
|
+
// Calculate bar height based on mic level
|
|
68
|
+
let barHeight = map(micLevel, 0, 1, 0, height);
|
|
69
|
+
|
|
70
|
+
// Draw full-width bar graph from bottom
|
|
71
|
+
fill(100, 200, 255);
|
|
72
|
+
noStroke();
|
|
73
|
+
rect(0, height - barHeight, width, barHeight);
|
|
74
|
+
|
|
75
|
+
// Draw threshold line
|
|
76
|
+
let thresholdY = height - map(threshold, 0, 1, 0, height);
|
|
77
|
+
stroke(255, 200, 0);
|
|
78
|
+
strokeWeight(2);
|
|
79
|
+
line(0, thresholdY, width, thresholdY);
|
|
80
|
+
|
|
81
|
+
// Label the threshold line
|
|
82
|
+
fill(255, 200, 0);
|
|
83
|
+
noStroke();
|
|
84
|
+
text("Threshold", width/2, thresholdY - 15);
|
|
85
|
+
|
|
86
|
+
// Instructions
|
|
87
|
+
fill(255);
|
|
88
|
+
text("Make noise or speak to see the level change", width/2, height - 60);
|
|
89
|
+
text("When level exceeds threshold, background changes color", width/2, height - 30);
|
|
90
|
+
}
|
|
91
|
+
else
|
|
92
|
+
{
|
|
93
|
+
// Microphone not available or permission not granted
|
|
94
|
+
fill(255, 100, 100);
|
|
95
|
+
text("Microphone not available", width/2, height/2);
|
|
96
|
+
text("On iOS: Tap to request microphone permission", width/2, height/2 + 30);
|
|
97
|
+
text("Check device compatibility", width/2, height/2 + 60);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ==============================================
|
|
102
|
+
// TOUCH EVENT FUNCTIONS
|
|
103
|
+
// ==============================================
|
|
104
|
+
|
|
105
|
+
// This function runs when a new touch begins
|
|
106
|
+
function touchStarted()
|
|
107
|
+
{
|
|
108
|
+
// Touch positions will be updated in draw() function
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// This function runs when a touch ends
|
|
113
|
+
function touchEnded()
|
|
114
|
+
{
|
|
115
|
+
// Touch positions will be updated in draw() function
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Basic Orientation - Mobile p5.js</title>
|
|
7
|
+
|
|
8
|
+
<!-- Basic CSS to remove browser defaults and align canvas -->
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
|
|
17
|
+
<!-- Load p5.js library -->
|
|
18
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.js"></script>
|
|
19
|
+
|
|
20
|
+
<!-- Load the mobile p5.js permissions library -->
|
|
21
|
+
<script src="https://cdn.jsdelivr.net/npm/mobile-p5-permissions@1.4.4/dist/p5.mobile-permissions.js"></script>
|
|
22
|
+
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<!-- Load the p5.js sketch -->
|
|
26
|
+
<script src="sketch.js"></script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// ==============================================
|
|
2
|
+
// BASIC ORIENTATION EXAMPLE
|
|
3
|
+
// ==============================================
|
|
4
|
+
// This example shows the device orientation
|
|
5
|
+
// values for x, y, and z rotation
|
|
6
|
+
//
|
|
7
|
+
// CONCEPTS COVERED:
|
|
8
|
+
// - Device orientation detection
|
|
9
|
+
// - Motion sensor permissions with enableGyroTap
|
|
10
|
+
// - rotationX, rotationY, rotationZ values
|
|
11
|
+
// - Simple display of sensor data
|
|
12
|
+
// - Global variables for sensor values
|
|
13
|
+
// ==============================================
|
|
14
|
+
|
|
15
|
+
// Variables to store orientation data
|
|
16
|
+
let orientationX = 0; // Rotation around X axis (front/back tilt)
|
|
17
|
+
let orientationY = 0; // Rotation around Y axis (left/right tilt)
|
|
18
|
+
let orientationZ = 0; // Rotation around Z axis (device rotation)
|
|
19
|
+
|
|
20
|
+
// ==============================================
|
|
21
|
+
// SETUP FUNCTION - Runs once when page loads
|
|
22
|
+
// ==============================================
|
|
23
|
+
function setup()
|
|
24
|
+
{
|
|
25
|
+
// Create a canvas that fills the entire screen
|
|
26
|
+
createCanvas(windowWidth, windowHeight);
|
|
27
|
+
|
|
28
|
+
// Set to show in Degrees
|
|
29
|
+
angleMode(DEGREES);
|
|
30
|
+
|
|
31
|
+
// Lock mobile gestures to prevent scrolling, zooming, etc.
|
|
32
|
+
lockGestures();
|
|
33
|
+
|
|
34
|
+
// Show debug panel to see what's happening
|
|
35
|
+
//showDebug();
|
|
36
|
+
|
|
37
|
+
// Try button instead of tap (more reliable)
|
|
38
|
+
enableGyroTap('ENABLE MOTION SENSORS', 'Requesting motion sensors...');
|
|
39
|
+
|
|
40
|
+
// Set text properties
|
|
41
|
+
textAlign(CENTER, CENTER);
|
|
42
|
+
textSize(32);
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ==============================================
|
|
48
|
+
// DRAW FUNCTION - Runs continuously
|
|
49
|
+
// ==============================================
|
|
50
|
+
function draw()
|
|
51
|
+
{
|
|
52
|
+
// Clear the screen
|
|
53
|
+
background(240, 240, 240);
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
// Check if sensors are working
|
|
58
|
+
if (window.sensorsEnabled)
|
|
59
|
+
{
|
|
60
|
+
background(200, 255, 200); // Light green when sensors active
|
|
61
|
+
|
|
62
|
+
// Update orientation values from device sensors ONLY when enabled
|
|
63
|
+
orientationX = rotationX;
|
|
64
|
+
orientationY = rotationY;
|
|
65
|
+
orientationZ = rotationZ;
|
|
66
|
+
|
|
67
|
+
// NOTE: You can use constrain() to keep values within a specific range
|
|
68
|
+
// Example: orientationX = constrain(rotationX, -90, 90);
|
|
69
|
+
// This would limit the X rotation to between -90 and 90 degrees
|
|
70
|
+
// Useful for mapping sensor values to specific ranges for animations or controls
|
|
71
|
+
// Learn more: https://p5js.org/reference/p5/constrain/
|
|
72
|
+
|
|
73
|
+
debug('angles',orientationX,orientationY,orientationZ);
|
|
74
|
+
|
|
75
|
+
// Display orientation values
|
|
76
|
+
fill(50, 50, 50); // Dark text
|
|
77
|
+
textAlign(CENTER, CENTER);
|
|
78
|
+
|
|
79
|
+
// Show current orientation values
|
|
80
|
+
textSize(24);
|
|
81
|
+
text("Device Orientation", width/2, height/2 - 100);
|
|
82
|
+
|
|
83
|
+
textSize(20);
|
|
84
|
+
text("X (Tilt Forward/Back): " + orientationX.toFixed(1) + "°", width/2, height/2 - 40);
|
|
85
|
+
text("Y (Tilt Left/Right): " + orientationY.toFixed(1) + "°", width/2, height/2);
|
|
86
|
+
text("Z (Rotation): " + orientationZ.toFixed(1) + "°", width/2, height/2 + 40);
|
|
87
|
+
|
|
88
|
+
// Instructions
|
|
89
|
+
textSize(16);
|
|
90
|
+
fill(100, 100, 100);
|
|
91
|
+
text("Tilt and rotate your device!", width/2, height/2 + 100);
|
|
92
|
+
}
|
|
93
|
+
else
|
|
94
|
+
{
|
|
95
|
+
// Instructions to enable sensors
|
|
96
|
+
fill(50, 50, 50); // Dark text
|
|
97
|
+
textAlign(CENTER, CENTER);
|
|
98
|
+
textSize(28);
|
|
99
|
+
fill(150, 50, 50); // Red text
|
|
100
|
+
text("Motion Sensors Disabled", width/2, height/2 - 40);
|
|
101
|
+
|
|
102
|
+
textSize(20);
|
|
103
|
+
fill(100, 100, 100);
|
|
104
|
+
text("Tap the screen to enable\\nmotion sensors", width/2, height/2 + 20);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ==============================================
|
|
109
|
+
// TOUCH EVENT FUNCTIONS
|
|
110
|
+
// ==============================================
|
|
111
|
+
// Note: Touch events are handled by enableGyroTap for permissions
|
|
112
|
+
|
|
113
|
+
function touchStarted()
|
|
114
|
+
{
|
|
115
|
+
// Permission handling is done by enableGyroTap
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function touchEnded()
|
|
120
|
+
{
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Rotational Velocity - Mobile p5.js</title>
|
|
7
|
+
|
|
8
|
+
<!-- Basic CSS to remove browser defaults and align canvas -->
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
|
|
17
|
+
<!-- Load p5.js library -->
|
|
18
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.js"></script>
|
|
19
|
+
|
|
20
|
+
<!-- Load the mobile p5.js permissions library -->
|
|
21
|
+
<script src="https://cdn.jsdelivr.net/npm/mobile-p5-permissions@1.4.4/dist/p5.mobile-permissions.js"></script>
|
|
22
|
+
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<!-- Load the p5.js sketch -->
|
|
26
|
+
<script src="sketch.js"></script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// ==============================================
|
|
2
|
+
// ROTATIONAL VELOCITY EXAMPLE
|
|
3
|
+
// ==============================================
|
|
4
|
+
// This example shows the rotational velocity
|
|
5
|
+
// by comparing current rotation with previous rotation
|
|
6
|
+
//
|
|
7
|
+
// CONCEPTS COVERED:
|
|
8
|
+
// - Device rotational velocity detection
|
|
9
|
+
// - Motion sensor permissions with enableGyroTap
|
|
10
|
+
// - rotationX, rotationY, rotationZ values
|
|
11
|
+
// - pRotationX, pRotationY, pRotationZ (previous frame values)
|
|
12
|
+
// - Calculating velocity as change over time
|
|
13
|
+
// - Global variables for velocity values
|
|
14
|
+
// ==============================================
|
|
15
|
+
|
|
16
|
+
// Variables to store current rotation data
|
|
17
|
+
let orientationX = 0; // Current rotation around X axis (front/back tilt)
|
|
18
|
+
let orientationY = 0; // Current rotation around Y axis (left/right tilt)
|
|
19
|
+
let orientationZ = 0; // Current rotation around Z axis (device rotation)
|
|
20
|
+
|
|
21
|
+
// Variables to store rotational velocity
|
|
22
|
+
let velocityX = 0; // Change in X rotation per frame
|
|
23
|
+
let velocityY = 0; // Change in Y rotation per frame
|
|
24
|
+
let velocityZ = 0; // Change in Z rotation per frame
|
|
25
|
+
|
|
26
|
+
// ==============================================
|
|
27
|
+
// SETUP FUNCTION - Runs once when page loads
|
|
28
|
+
// ==============================================
|
|
29
|
+
function setup()
|
|
30
|
+
{
|
|
31
|
+
// Create a canvas that fills the entire screen
|
|
32
|
+
createCanvas(windowWidth, windowHeight);
|
|
33
|
+
|
|
34
|
+
// Lock mobile gestures to prevent scrolling, zooming, etc.
|
|
35
|
+
lockGestures();
|
|
36
|
+
|
|
37
|
+
// Enable motion sensors with tap-to-start
|
|
38
|
+
enableGyroTap('Tap screen to enable motion sensors');
|
|
39
|
+
|
|
40
|
+
// Set text properties
|
|
41
|
+
textAlign(CENTER, CENTER);
|
|
42
|
+
textSize(32);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ==============================================
|
|
46
|
+
// DRAW FUNCTION - Runs continuously
|
|
47
|
+
// ==============================================
|
|
48
|
+
function draw()
|
|
49
|
+
{
|
|
50
|
+
// Clear the screen
|
|
51
|
+
background(240, 240, 240);
|
|
52
|
+
|
|
53
|
+
// Check if sensors are working
|
|
54
|
+
if (window.sensorsEnabled)
|
|
55
|
+
{
|
|
56
|
+
background(200, 255, 200); // Light green when sensors active
|
|
57
|
+
|
|
58
|
+
// Update orientation values from device sensors ONLY when enabled
|
|
59
|
+
orientationX = rotationX;
|
|
60
|
+
orientationY = rotationY;
|
|
61
|
+
orientationZ = rotationZ;
|
|
62
|
+
|
|
63
|
+
// Calculate rotational velocity (change from previous frame)
|
|
64
|
+
// p5.js provides pRotationX, pRotationY, pRotationZ for previous frame values
|
|
65
|
+
velocityX = orientationX - pRotationX;
|
|
66
|
+
velocityY = orientationY - pRotationY;
|
|
67
|
+
velocityZ = orientationZ - pRotationZ;
|
|
68
|
+
|
|
69
|
+
// NOTE: You can use constrain() to keep velocity values within a specific range
|
|
70
|
+
// Example: velocityX = constrain(velocityX, -10, 10);
|
|
71
|
+
// This would limit the X velocity to between -10 and 10 degrees per frame
|
|
72
|
+
// Useful for creating smooth animations or preventing extreme values
|
|
73
|
+
// Learn more: https://p5js.org/reference/p5/constrain/
|
|
74
|
+
|
|
75
|
+
// Display current orientation values
|
|
76
|
+
fill(50, 50, 50); // Dark text
|
|
77
|
+
textAlign(CENTER, CENTER);
|
|
78
|
+
|
|
79
|
+
// Show current orientation title
|
|
80
|
+
textSize(24);
|
|
81
|
+
text("Device Rotational Velocity", width/2, height/2 - 140);
|
|
82
|
+
|
|
83
|
+
// Show current rotation values
|
|
84
|
+
textSize(18);
|
|
85
|
+
fill(80, 80, 80);
|
|
86
|
+
text("Current Rotation:", width/2, height/2 - 100);
|
|
87
|
+
|
|
88
|
+
textSize(16);
|
|
89
|
+
text("X: " + orientationX.toFixed(1) + "°", width/2, height/2 - 80);
|
|
90
|
+
text("Y: " + orientationY.toFixed(1) + "°", width/2, height/2 - 60);
|
|
91
|
+
text("Z: " + orientationZ.toFixed(1) + "°", width/2, height/2 - 40);
|
|
92
|
+
|
|
93
|
+
// Show velocity values (change per frame)
|
|
94
|
+
textSize(18);
|
|
95
|
+
fill(150, 50, 50); // Red text for velocity
|
|
96
|
+
text("Rotational Velocity (°/frame):", width/2, height/2);
|
|
97
|
+
|
|
98
|
+
textSize(16);
|
|
99
|
+
text("X Velocity: " + velocityX.toFixed(2) + "°/frame", width/2, height/2 + 20);
|
|
100
|
+
text("Y Velocity: " + velocityY.toFixed(2) + "°/frame", width/2, height/2 + 40);
|
|
101
|
+
text("Z Velocity: " + velocityZ.toFixed(2) + "°/frame", width/2, height/2 + 60);
|
|
102
|
+
|
|
103
|
+
// Show velocity magnitude (total rotational speed)
|
|
104
|
+
let totalVelocity = sqrt(velocityX * velocityX + velocityY * velocityY + velocityZ * velocityZ);
|
|
105
|
+
textSize(18);
|
|
106
|
+
fill(50, 100, 150); // Blue text for total
|
|
107
|
+
text("Total Velocity: " + totalVelocity.toFixed(2) + "°/frame", width/2, height/2 + 90);
|
|
108
|
+
|
|
109
|
+
// Instructions
|
|
110
|
+
textSize(14);
|
|
111
|
+
fill(100, 100, 100);
|
|
112
|
+
text("Rotate your device quickly to see velocity changes!", width/2, height/2 + 130);
|
|
113
|
+
}
|
|
114
|
+
else
|
|
115
|
+
{
|
|
116
|
+
// Instructions to enable sensors
|
|
117
|
+
fill(50, 50, 50); // Dark text
|
|
118
|
+
textAlign(CENTER, CENTER);
|
|
119
|
+
textSize(28);
|
|
120
|
+
fill(150, 50, 50); // Red text
|
|
121
|
+
text("Motion Sensors Disabled", width/2, height/2 - 40);
|
|
122
|
+
|
|
123
|
+
textSize(20);
|
|
124
|
+
fill(100, 100, 100);
|
|
125
|
+
text("Tap the screen to enable\\nmotion sensors", width/2, height/2 + 20);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ==============================================
|
|
130
|
+
// TOUCH EVENT FUNCTIONS
|
|
131
|
+
// ==============================================
|
|
132
|
+
// Note: Touch events are handled by enableGyroTap for permissions
|
|
133
|
+
|
|
134
|
+
function touchStarted()
|
|
135
|
+
{
|
|
136
|
+
// Permission handling is done by enableGyroTap
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function touchEnded()
|
|
141
|
+
{
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Basic Velocity - Mobile p5.js</title>
|
|
7
|
+
|
|
8
|
+
<!-- Basic CSS to remove browser defaults and align canvas -->
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
|
|
17
|
+
<!-- Load p5.js library -->
|
|
18
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.js"></script>
|
|
19
|
+
|
|
20
|
+
<!-- Load the mobile p5.js permissions library -->
|
|
21
|
+
<script src="https://cdn.jsdelivr.net/npm/mobile-p5-permissions@1.4.4/dist/p5.mobile-permissions.js"></script>
|
|
22
|
+
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<!-- Load the p5.js sketch -->
|
|
26
|
+
<script src="sketch.js"></script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Device acceleration example
|
|
2
|
+
// Demonstrates reading accelerationX, Y, Z values from device motion sensors
|
|
3
|
+
// Acceleration is measured in m/s² (meters per second squared)
|
|
4
|
+
|
|
5
|
+
let backgroundColor;
|
|
6
|
+
|
|
7
|
+
function setup()
|
|
8
|
+
{
|
|
9
|
+
createCanvas(windowWidth, windowHeight);
|
|
10
|
+
backgroundColor = color(50, 50, 50);
|
|
11
|
+
textAlign(CENTER, CENTER);
|
|
12
|
+
textSize(16);
|
|
13
|
+
|
|
14
|
+
// Request permission for motion sensors on iOS
|
|
15
|
+
enableGyroTap();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function draw()
|
|
19
|
+
{
|
|
20
|
+
background(backgroundColor);
|
|
21
|
+
|
|
22
|
+
// Check if motion sensors are available
|
|
23
|
+
if (window.sensorsEnabled)
|
|
24
|
+
{
|
|
25
|
+
// Display current acceleration values
|
|
26
|
+
fill(255);
|
|
27
|
+
text("Device Acceleration", width/2, height/6);
|
|
28
|
+
|
|
29
|
+
// Display individual acceleration values
|
|
30
|
+
text("X: " + nf(accelerationX, 1, 2) + " m/s²", width/2, height/6 + 40);
|
|
31
|
+
text("Y: " + nf(accelerationY, 1, 2) + " m/s²", width/2, height/6 + 70);
|
|
32
|
+
text("Z: " + nf(accelerationZ, 1, 2) + " m/s²", width/2, height/6 + 100);
|
|
33
|
+
|
|
34
|
+
// Calculate total acceleration magnitude using 3D distance formula
|
|
35
|
+
let totalAcceleration = sqrt(accelerationX * accelerationX +
|
|
36
|
+
accelerationY * accelerationY +
|
|
37
|
+
accelerationZ * accelerationZ);
|
|
38
|
+
|
|
39
|
+
text("Total: " + nf(totalAcceleration, 1, 2) + " m/s²", width/2, height/6 + 140);
|
|
40
|
+
|
|
41
|
+
// Visual representation using bars
|
|
42
|
+
fill(255, 100, 100); // Red for X
|
|
43
|
+
rect(width/2 - 120, height/2, map(abs(accelerationX), 0, 20, 0, 100), 20);
|
|
44
|
+
|
|
45
|
+
fill(100, 255, 100); // Green for Y
|
|
46
|
+
rect(width/2 - 120, height/2 + 30, map(abs(accelerationY), 0, 20, 0, 100), 20);
|
|
47
|
+
|
|
48
|
+
fill(100, 100, 255); // Blue for Z
|
|
49
|
+
rect(width/2 - 120, height/2 + 60, map(abs(accelerationZ), 0, 20, 0, 100), 20);
|
|
50
|
+
|
|
51
|
+
// Labels for the bars
|
|
52
|
+
fill(255);
|
|
53
|
+
text("X", width/2 - 140, height/2 + 10);
|
|
54
|
+
text("Y", width/2 - 140, height/2 + 40);
|
|
55
|
+
text("Z", width/2 - 140, height/2 + 70);
|
|
56
|
+
|
|
57
|
+
// Instructions
|
|
58
|
+
text("Move your device to see acceleration changes", width/2, height - 60);
|
|
59
|
+
text("Shake, tilt, or move the device in different directions", width/2, height - 30);
|
|
60
|
+
}
|
|
61
|
+
else
|
|
62
|
+
{
|
|
63
|
+
// Motion sensors not available or permission not granted
|
|
64
|
+
fill(255, 100, 100);
|
|
65
|
+
text("Motion sensors not available", width/2, height/2);
|
|
66
|
+
text("On iOS: Tap to request motion permission", width/2, height/2 + 30);
|
|
67
|
+
text("Check device compatibility", width/2, height/2 + 60);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ==============================================
|
|
72
|
+
// TOUCH EVENT FUNCTIONS
|
|
73
|
+
// ==============================================
|
|
74
|
+
|
|
75
|
+
// This function runs when a new touch begins
|
|
76
|
+
function touchStarted()
|
|
77
|
+
{
|
|
78
|
+
// Touch positions will be updated in draw() function
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// This function runs when a touch ends
|
|
83
|
+
function touchEnded()
|
|
84
|
+
{
|
|
85
|
+
// Touch positions will be updated in draw() function
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Dual Audio Playback - Mobile p5.js</title>
|
|
7
|
+
|
|
8
|
+
<!-- Basic CSS to remove browser defaults and align canvas -->
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
|
|
17
|
+
<!-- Load p5.js library -->
|
|
18
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
|
|
19
|
+
|
|
20
|
+
<!-- Load p5.sound library for audio -->
|
|
21
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/addons/p5.sound.min.js"></script>
|
|
22
|
+
|
|
23
|
+
<!-- Load the mobile p5.js permissions library -->
|
|
24
|
+
<script src="https://cdn.jsdelivr.net/npm/mobile-p5-permissions@1.4.4/dist/p5.mobile-permissions.min.js"></script>
|
|
25
|
+
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<!-- Load the p5.js sketch -->
|
|
29
|
+
<script src="sketch.js"></script>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|