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,240 @@
|
|
|
1
|
+
// =============================================
|
|
2
|
+
// MICROPHONE PERMISSIONS & GESTURE HANDLING
|
|
3
|
+
// For projects that only need microphone/audio input
|
|
4
|
+
// Students don't need to modify this
|
|
5
|
+
// =============================================
|
|
6
|
+
|
|
7
|
+
// Global flag for sketch.js to check
|
|
8
|
+
window.micEnabled = false;
|
|
9
|
+
|
|
10
|
+
// Store references
|
|
11
|
+
let startButton;
|
|
12
|
+
let statusText;
|
|
13
|
+
|
|
14
|
+
// =========================================
|
|
15
|
+
// INITIALIZATION
|
|
16
|
+
// =========================================
|
|
17
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
18
|
+
startButton = document.getElementById('startButton');
|
|
19
|
+
statusText = document.getElementById('statusText');
|
|
20
|
+
|
|
21
|
+
// Add click event listener to start button
|
|
22
|
+
startButton.addEventListener('click', handleMicrophonePermissionRequest);
|
|
23
|
+
|
|
24
|
+
// Initialize other event listeners
|
|
25
|
+
initializeGestureBlocking();
|
|
26
|
+
initializeP5TouchOverrides();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// =========================================
|
|
30
|
+
// MICROPHONE PERMISSION HANDLING
|
|
31
|
+
// =========================================
|
|
32
|
+
async function handleMicrophonePermissionRequest() {
|
|
33
|
+
startButton.classList.add('hidden');
|
|
34
|
+
statusText.classList.remove('hidden');
|
|
35
|
+
statusText.textContent = 'Requesting microphone permissions...';
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// Start audio context
|
|
39
|
+
statusText.textContent = 'Enabling audio input...';
|
|
40
|
+
|
|
41
|
+
// Handle p5.sound
|
|
42
|
+
if (typeof userStartAudio !== 'undefined') {
|
|
43
|
+
await userStartAudio();
|
|
44
|
+
|
|
45
|
+
// If there's a global mic object created by sketch.js, start it
|
|
46
|
+
if (typeof mic !== 'undefined' && mic && mic.start) {
|
|
47
|
+
statusText.textContent = 'Starting microphone...';
|
|
48
|
+
mic.start();
|
|
49
|
+
window.micEnabled = true;
|
|
50
|
+
console.log('Microphone enabled. Use mic.getLevel() to get audio input level.');
|
|
51
|
+
} else {
|
|
52
|
+
console.log('No microphone object found. Create one in sketch.js with: mic = new p5.AudioIn();');
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
console.log('p5.sound not detected. Make sure p5.sound.js is loaded.');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Hide status text
|
|
59
|
+
statusText.classList.add('hidden');
|
|
60
|
+
|
|
61
|
+
// Call setup again if it exists (to reinitialize with permissions)
|
|
62
|
+
if (typeof userSetupComplete === 'function') {
|
|
63
|
+
userSetupComplete();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error('Microphone permission error:', error);
|
|
68
|
+
statusText.textContent = 'Error accessing microphone: ' + error.message;
|
|
69
|
+
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
statusText.classList.add('hidden');
|
|
72
|
+
}, 3000);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// =========================================
|
|
77
|
+
// GESTURE PREVENTION INITIALIZATION
|
|
78
|
+
// =========================================
|
|
79
|
+
function initializeGestureBlocking() {
|
|
80
|
+
// Prevent back navigation
|
|
81
|
+
window.history.pushState(null, '', window.location.href);
|
|
82
|
+
window.onpopstate = function() {
|
|
83
|
+
window.history.pushState(null, '', window.location.href);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Warn before leaving
|
|
87
|
+
window.addEventListener('beforeunload', function(e) {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
e.returnValue = '';
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Initialize edge swipe prevention
|
|
93
|
+
initializeEdgeSwipePrevention();
|
|
94
|
+
|
|
95
|
+
// Initialize other gesture prevention
|
|
96
|
+
initializeOtherGesturePrevention();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// =========================================
|
|
100
|
+
// EDGE SWIPE PREVENTION
|
|
101
|
+
// =========================================
|
|
102
|
+
function initializeEdgeSwipePrevention() {
|
|
103
|
+
let touchStartX = 0;
|
|
104
|
+
let touchStartY = 0;
|
|
105
|
+
const edgeThreshold = 20;
|
|
106
|
+
|
|
107
|
+
document.addEventListener('touchstart', function(e) {
|
|
108
|
+
if (e.touches && e.touches.length > 0) {
|
|
109
|
+
touchStartX = e.touches[0].clientX;
|
|
110
|
+
touchStartY = e.touches[0].clientY;
|
|
111
|
+
|
|
112
|
+
// Prevent edge swipes
|
|
113
|
+
if (touchStartX < edgeThreshold ||
|
|
114
|
+
touchStartX > window.innerWidth - edgeThreshold) {
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, { passive: false, capture: true });
|
|
119
|
+
|
|
120
|
+
document.addEventListener('touchmove', function(e) {
|
|
121
|
+
if (!e.touches || e.touches.length === 0) return;
|
|
122
|
+
|
|
123
|
+
let currentX = e.touches[0].clientX;
|
|
124
|
+
let currentY = e.touches[0].clientY;
|
|
125
|
+
let deltaX = currentX - touchStartX;
|
|
126
|
+
let deltaY = currentY - touchStartY;
|
|
127
|
+
|
|
128
|
+
// Prevent horizontal edge swipes (back/forward)
|
|
129
|
+
if ((touchStartX < edgeThreshold && deltaX > 0) ||
|
|
130
|
+
(touchStartX > window.innerWidth - edgeThreshold && deltaX < 0)) {
|
|
131
|
+
e.preventDefault();
|
|
132
|
+
e.stopPropagation();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Prevent pull-to-refresh
|
|
136
|
+
if (window.pageYOffset === 0 && deltaY > 0) {
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Always prevent on canvas
|
|
141
|
+
if (e.target && e.target.tagName === 'CANVAS') {
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
}
|
|
144
|
+
}, { passive: false, capture: true });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// =========================================
|
|
148
|
+
// OTHER GESTURE PREVENTION
|
|
149
|
+
// =========================================
|
|
150
|
+
function initializeOtherGesturePrevention() {
|
|
151
|
+
// Prevent pinch zoom
|
|
152
|
+
document.addEventListener('gesturestart', function(e) {
|
|
153
|
+
e.preventDefault();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
document.addEventListener('gesturechange', function(e) {
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
document.addEventListener('gestureend', function(e) {
|
|
161
|
+
e.preventDefault();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Prevent double-tap zoom
|
|
165
|
+
let lastTouchEnd = 0;
|
|
166
|
+
document.addEventListener('touchend', function(e) {
|
|
167
|
+
const now = Date.now();
|
|
168
|
+
if (now - lastTouchEnd <= 300) {
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
}
|
|
171
|
+
lastTouchEnd = now;
|
|
172
|
+
}, false);
|
|
173
|
+
|
|
174
|
+
// Prevent long-press context menu
|
|
175
|
+
window.oncontextmenu = function(e) {
|
|
176
|
+
e.preventDefault();
|
|
177
|
+
e.stopPropagation();
|
|
178
|
+
return false;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// =========================================
|
|
183
|
+
// P5.JS GESTURE OVERRIDE HELPERS
|
|
184
|
+
// =========================================
|
|
185
|
+
function initializeP5TouchOverrides() {
|
|
186
|
+
// Wait for p5 to be ready
|
|
187
|
+
setTimeout(() => {
|
|
188
|
+
if (window._setupDone) {
|
|
189
|
+
overrideP5Touch();
|
|
190
|
+
} else {
|
|
191
|
+
// Try again after setup
|
|
192
|
+
const checkP5 = setInterval(() => {
|
|
193
|
+
if (window._setupDone) {
|
|
194
|
+
overrideP5Touch();
|
|
195
|
+
clearInterval(checkP5);
|
|
196
|
+
}
|
|
197
|
+
}, 100);
|
|
198
|
+
}
|
|
199
|
+
}, 100);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function overrideP5Touch() {
|
|
203
|
+
const origTouchStarted = window.touchStarted || function() {};
|
|
204
|
+
const origTouchMoved = window.touchMoved || function() {};
|
|
205
|
+
const origTouchEnded = window.touchEnded || function() {};
|
|
206
|
+
const origMousePressed = window.mousePressed || function() {};
|
|
207
|
+
const origMouseDragged = window.mouseDragged || function() {};
|
|
208
|
+
const origMouseReleased = window.mouseReleased || function() {};
|
|
209
|
+
|
|
210
|
+
// Ensure all touch functions return false
|
|
211
|
+
window.touchStarted = function(e) {
|
|
212
|
+
origTouchStarted(e);
|
|
213
|
+
return false;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
window.touchMoved = function(e) {
|
|
217
|
+
origTouchMoved(e);
|
|
218
|
+
return false;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
window.touchEnded = function(e) {
|
|
222
|
+
origTouchEnded(e);
|
|
223
|
+
return false;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
window.mousePressed = function(e) {
|
|
227
|
+
origMousePressed(e);
|
|
228
|
+
return false;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
window.mouseDragged = function(e) {
|
|
232
|
+
origMouseDragged(e);
|
|
233
|
+
return false;
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
window.mouseReleased = function(e) {
|
|
237
|
+
origMouseReleased(e);
|
|
238
|
+
return false;
|
|
239
|
+
};
|
|
240
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// =============================================
|
|
2
|
+
// GESTURE BLOCKING ONLY
|
|
3
|
+
// For projects that only need touch input and gesture prevention
|
|
4
|
+
// No sensor or microphone permissions requested
|
|
5
|
+
// Students don't need to modify this
|
|
6
|
+
// =============================================
|
|
7
|
+
|
|
8
|
+
// Store references
|
|
9
|
+
let startButton;
|
|
10
|
+
let statusText;
|
|
11
|
+
|
|
12
|
+
// =========================================
|
|
13
|
+
// INITIALIZATION
|
|
14
|
+
// =========================================
|
|
15
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
16
|
+
startButton = document.getElementById('startButton');
|
|
17
|
+
statusText = document.getElementById('statusText');
|
|
18
|
+
|
|
19
|
+
// Add click event listener to start button
|
|
20
|
+
startButton.addEventListener('click', handleGestureOnlySetup);
|
|
21
|
+
|
|
22
|
+
// Initialize gesture blocking immediately
|
|
23
|
+
initializeGestureBlocking();
|
|
24
|
+
initializeP5TouchOverrides();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// =========================================
|
|
28
|
+
// GESTURE-ONLY SETUP
|
|
29
|
+
// =========================================
|
|
30
|
+
function handleGestureOnlySetup() {
|
|
31
|
+
startButton.classList.add('hidden');
|
|
32
|
+
statusText.classList.remove('hidden');
|
|
33
|
+
statusText.textContent = 'Enabling touch input...';
|
|
34
|
+
|
|
35
|
+
// No permissions needed, just hide the button and enable touch
|
|
36
|
+
console.log('Gesture blocking enabled. Touch input available: touchX, touchY, touches[], mouseX, mouseY');
|
|
37
|
+
|
|
38
|
+
// Hide status text after brief moment
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
statusText.classList.add('hidden');
|
|
41
|
+
}, 500);
|
|
42
|
+
|
|
43
|
+
// Call setup again if it exists (to reinitialize)
|
|
44
|
+
if (typeof userSetupComplete === 'function') {
|
|
45
|
+
userSetupComplete();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// =========================================
|
|
50
|
+
// GESTURE PREVENTION INITIALIZATION
|
|
51
|
+
// =========================================
|
|
52
|
+
function initializeGestureBlocking() {
|
|
53
|
+
// Prevent back navigation
|
|
54
|
+
window.history.pushState(null, '', window.location.href);
|
|
55
|
+
window.onpopstate = function() {
|
|
56
|
+
window.history.pushState(null, '', window.location.href);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Warn before leaving
|
|
60
|
+
window.addEventListener('beforeunload', function(e) {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
e.returnValue = '';
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Initialize edge swipe prevention
|
|
66
|
+
initializeEdgeSwipePrevention();
|
|
67
|
+
|
|
68
|
+
// Initialize other gesture prevention
|
|
69
|
+
initializeOtherGesturePrevention();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// =========================================
|
|
73
|
+
// EDGE SWIPE PREVENTION
|
|
74
|
+
// =========================================
|
|
75
|
+
function initializeEdgeSwipePrevention() {
|
|
76
|
+
let touchStartX = 0;
|
|
77
|
+
let touchStartY = 0;
|
|
78
|
+
const edgeThreshold = 20;
|
|
79
|
+
|
|
80
|
+
document.addEventListener('touchstart', function(e) {
|
|
81
|
+
if (e.touches && e.touches.length > 0) {
|
|
82
|
+
touchStartX = e.touches[0].clientX;
|
|
83
|
+
touchStartY = e.touches[0].clientY;
|
|
84
|
+
|
|
85
|
+
// Prevent edge swipes
|
|
86
|
+
if (touchStartX < edgeThreshold ||
|
|
87
|
+
touchStartX > window.innerWidth - edgeThreshold) {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}, { passive: false, capture: true });
|
|
92
|
+
|
|
93
|
+
document.addEventListener('touchmove', function(e) {
|
|
94
|
+
if (!e.touches || e.touches.length === 0) return;
|
|
95
|
+
|
|
96
|
+
let currentX = e.touches[0].clientX;
|
|
97
|
+
let currentY = e.touches[0].clientY;
|
|
98
|
+
let deltaX = currentX - touchStartX;
|
|
99
|
+
let deltaY = currentY - touchStartY;
|
|
100
|
+
|
|
101
|
+
// Prevent horizontal edge swipes (back/forward)
|
|
102
|
+
if ((touchStartX < edgeThreshold && deltaX > 0) ||
|
|
103
|
+
(touchStartX > window.innerWidth - edgeThreshold && deltaX < 0)) {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
e.stopPropagation();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Prevent pull-to-refresh
|
|
109
|
+
if (window.pageYOffset === 0 && deltaY > 0) {
|
|
110
|
+
e.preventDefault();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Always prevent on canvas
|
|
114
|
+
if (e.target && e.target.tagName === 'CANVAS') {
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
}
|
|
117
|
+
}, { passive: false, capture: true });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// =========================================
|
|
121
|
+
// OTHER GESTURE PREVENTION
|
|
122
|
+
// =========================================
|
|
123
|
+
function initializeOtherGesturePrevention() {
|
|
124
|
+
// Prevent pinch zoom
|
|
125
|
+
document.addEventListener('gesturestart', function(e) {
|
|
126
|
+
e.preventDefault();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
document.addEventListener('gesturechange', function(e) {
|
|
130
|
+
e.preventDefault();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
document.addEventListener('gestureend', function(e) {
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Prevent double-tap zoom
|
|
138
|
+
let lastTouchEnd = 0;
|
|
139
|
+
document.addEventListener('touchend', function(e) {
|
|
140
|
+
const now = Date.now();
|
|
141
|
+
if (now - lastTouchEnd <= 300) {
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
}
|
|
144
|
+
lastTouchEnd = now;
|
|
145
|
+
}, false);
|
|
146
|
+
|
|
147
|
+
// Prevent long-press context menu
|
|
148
|
+
window.oncontextmenu = function(e) {
|
|
149
|
+
e.preventDefault();
|
|
150
|
+
e.stopPropagation();
|
|
151
|
+
return false;
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// =========================================
|
|
156
|
+
// P5.JS GESTURE OVERRIDE HELPERS
|
|
157
|
+
// =========================================
|
|
158
|
+
function initializeP5TouchOverrides() {
|
|
159
|
+
// Wait for p5 to be ready
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
if (window._setupDone) {
|
|
162
|
+
overrideP5Touch();
|
|
163
|
+
} else {
|
|
164
|
+
// Try again after setup
|
|
165
|
+
const checkP5 = setInterval(() => {
|
|
166
|
+
if (window._setupDone) {
|
|
167
|
+
overrideP5Touch();
|
|
168
|
+
clearInterval(checkP5);
|
|
169
|
+
}
|
|
170
|
+
}, 100);
|
|
171
|
+
}
|
|
172
|
+
}, 100);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function overrideP5Touch() {
|
|
176
|
+
const origTouchStarted = window.touchStarted || function() {};
|
|
177
|
+
const origTouchMoved = window.touchMoved || function() {};
|
|
178
|
+
const origTouchEnded = window.touchEnded || function() {};
|
|
179
|
+
const origMousePressed = window.mousePressed || function() {};
|
|
180
|
+
const origMouseDragged = window.mouseDragged || function() {};
|
|
181
|
+
const origMouseReleased = window.mouseReleased || function() {};
|
|
182
|
+
|
|
183
|
+
// Ensure all touch functions return false
|
|
184
|
+
window.touchStarted = function(e) {
|
|
185
|
+
origTouchStarted(e);
|
|
186
|
+
return false;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
window.touchMoved = function(e) {
|
|
190
|
+
origTouchMoved(e);
|
|
191
|
+
return false;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
window.touchEnded = function(e) {
|
|
195
|
+
origTouchEnded(e);
|
|
196
|
+
return false;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
window.mousePressed = function(e) {
|
|
200
|
+
origMousePressed(e);
|
|
201
|
+
return false;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
window.mouseDragged = function(e) {
|
|
205
|
+
origMouseDragged(e);
|
|
206
|
+
return false;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
window.mouseReleased = function(e) {
|
|
210
|
+
origMouseReleased(e);
|
|
211
|
+
return false;
|
|
212
|
+
};
|
|
213
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// =============================================
|
|
2
|
+
// GYROSCOPE/ACCELEROMETER PERMISSIONS & GESTURE HANDLING
|
|
3
|
+
// For projects that only need motion/orientation sensor data
|
|
4
|
+
// Students don't need to modify this
|
|
5
|
+
// =============================================
|
|
6
|
+
|
|
7
|
+
// Global flag for sketch.js to check
|
|
8
|
+
window.sensorsEnabled = false;
|
|
9
|
+
|
|
10
|
+
// Store references
|
|
11
|
+
let startButton;
|
|
12
|
+
let statusText;
|
|
13
|
+
|
|
14
|
+
// =========================================
|
|
15
|
+
// INITIALIZATION
|
|
16
|
+
// =========================================
|
|
17
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
18
|
+
startButton = document.getElementById('startButton');
|
|
19
|
+
statusText = document.getElementById('statusText');
|
|
20
|
+
|
|
21
|
+
// Add click event listener to start button
|
|
22
|
+
startButton.addEventListener('click', handleGyroPermissionRequest);
|
|
23
|
+
|
|
24
|
+
// Initialize other event listeners
|
|
25
|
+
initializeGestureBlocking();
|
|
26
|
+
initializeP5TouchOverrides();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// =========================================
|
|
30
|
+
// GYROSCOPE/ACCELEROMETER PERMISSION HANDLING
|
|
31
|
+
// =========================================
|
|
32
|
+
async function handleGyroPermissionRequest() {
|
|
33
|
+
startButton.classList.add('hidden');
|
|
34
|
+
statusText.classList.remove('hidden');
|
|
35
|
+
statusText.textContent = 'Requesting motion sensor permissions...';
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// Request motion sensor permissions (iOS 13+)
|
|
39
|
+
if (typeof DeviceOrientationEvent !== 'undefined' &&
|
|
40
|
+
typeof DeviceOrientationEvent.requestPermission === 'function') {
|
|
41
|
+
|
|
42
|
+
statusText.textContent = 'Requesting gyroscope access...';
|
|
43
|
+
|
|
44
|
+
const orientationPermission = await DeviceOrientationEvent.requestPermission();
|
|
45
|
+
console.log('Orientation permission:', orientationPermission);
|
|
46
|
+
|
|
47
|
+
if (typeof DeviceMotionEvent !== 'undefined' &&
|
|
48
|
+
typeof DeviceMotionEvent.requestPermission === 'function') {
|
|
49
|
+
|
|
50
|
+
statusText.textContent = 'Requesting accelerometer access...';
|
|
51
|
+
const motionPermission = await DeviceMotionEvent.requestPermission();
|
|
52
|
+
console.log('Motion permission:', motionPermission);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Mark sensors as enabled
|
|
57
|
+
window.sensorsEnabled = true;
|
|
58
|
+
|
|
59
|
+
// Hide status text
|
|
60
|
+
statusText.classList.add('hidden');
|
|
61
|
+
|
|
62
|
+
console.log('Motion sensors enabled. Available data: rotationX, rotationY, rotationZ, accelerationX, accelerationY, accelerationZ');
|
|
63
|
+
|
|
64
|
+
// Call setup again if it exists (to reinitialize with permissions)
|
|
65
|
+
if (typeof userSetupComplete === 'function') {
|
|
66
|
+
userSetupComplete();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error('Motion sensor permission error:', error);
|
|
71
|
+
statusText.textContent = 'Error accessing motion sensors: ' + error.message;
|
|
72
|
+
|
|
73
|
+
// Still enable what we can
|
|
74
|
+
window.sensorsEnabled = true;
|
|
75
|
+
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
statusText.classList.add('hidden');
|
|
78
|
+
}, 3000);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// =========================================
|
|
83
|
+
// GESTURE PREVENTION INITIALIZATION
|
|
84
|
+
// =========================================
|
|
85
|
+
function initializeGestureBlocking() {
|
|
86
|
+
// Prevent back navigation
|
|
87
|
+
window.history.pushState(null, '', window.location.href);
|
|
88
|
+
window.onpopstate = function() {
|
|
89
|
+
window.history.pushState(null, '', window.location.href);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Warn before leaving
|
|
93
|
+
window.addEventListener('beforeunload', function(e) {
|
|
94
|
+
e.preventDefault();
|
|
95
|
+
e.returnValue = '';
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Initialize edge swipe prevention
|
|
99
|
+
initializeEdgeSwipePrevention();
|
|
100
|
+
|
|
101
|
+
// Initialize other gesture prevention
|
|
102
|
+
initializeOtherGesturePrevention();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// =========================================
|
|
106
|
+
// EDGE SWIPE PREVENTION
|
|
107
|
+
// =========================================
|
|
108
|
+
function initializeEdgeSwipePrevention() {
|
|
109
|
+
let touchStartX = 0;
|
|
110
|
+
let touchStartY = 0;
|
|
111
|
+
const edgeThreshold = 20;
|
|
112
|
+
|
|
113
|
+
document.addEventListener('touchstart', function(e) {
|
|
114
|
+
if (e.touches && e.touches.length > 0) {
|
|
115
|
+
touchStartX = e.touches[0].clientX;
|
|
116
|
+
touchStartY = e.touches[0].clientY;
|
|
117
|
+
|
|
118
|
+
// Prevent edge swipes
|
|
119
|
+
if (touchStartX < edgeThreshold ||
|
|
120
|
+
touchStartX > window.innerWidth - edgeThreshold) {
|
|
121
|
+
e.preventDefault();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}, { passive: false, capture: true });
|
|
125
|
+
|
|
126
|
+
document.addEventListener('touchmove', function(e) {
|
|
127
|
+
if (!e.touches || e.touches.length === 0) return;
|
|
128
|
+
|
|
129
|
+
let currentX = e.touches[0].clientX;
|
|
130
|
+
let currentY = e.touches[0].clientY;
|
|
131
|
+
let deltaX = currentX - touchStartX;
|
|
132
|
+
let deltaY = currentY - touchStartY;
|
|
133
|
+
|
|
134
|
+
// Prevent horizontal edge swipes (back/forward)
|
|
135
|
+
if ((touchStartX < edgeThreshold && deltaX > 0) ||
|
|
136
|
+
(touchStartX > window.innerWidth - edgeThreshold && deltaX < 0)) {
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
e.stopPropagation();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Prevent pull-to-refresh
|
|
142
|
+
if (window.pageYOffset === 0 && deltaY > 0) {
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Always prevent on canvas
|
|
147
|
+
if (e.target && e.target.tagName === 'CANVAS') {
|
|
148
|
+
e.preventDefault();
|
|
149
|
+
}
|
|
150
|
+
}, { passive: false, capture: true });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// =========================================
|
|
154
|
+
// OTHER GESTURE PREVENTION
|
|
155
|
+
// =========================================
|
|
156
|
+
function initializeOtherGesturePrevention() {
|
|
157
|
+
// Prevent pinch zoom
|
|
158
|
+
document.addEventListener('gesturestart', function(e) {
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
document.addEventListener('gesturechange', function(e) {
|
|
163
|
+
e.preventDefault();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
document.addEventListener('gestureend', function(e) {
|
|
167
|
+
e.preventDefault();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Prevent double-tap zoom
|
|
171
|
+
let lastTouchEnd = 0;
|
|
172
|
+
document.addEventListener('touchend', function(e) {
|
|
173
|
+
const now = Date.now();
|
|
174
|
+
if (now - lastTouchEnd <= 300) {
|
|
175
|
+
e.preventDefault();
|
|
176
|
+
}
|
|
177
|
+
lastTouchEnd = now;
|
|
178
|
+
}, false);
|
|
179
|
+
|
|
180
|
+
// Prevent long-press context menu
|
|
181
|
+
window.oncontextmenu = function(e) {
|
|
182
|
+
e.preventDefault();
|
|
183
|
+
e.stopPropagation();
|
|
184
|
+
return false;
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// =========================================
|
|
189
|
+
// P5.JS GESTURE OVERRIDE HELPERS
|
|
190
|
+
// =========================================
|
|
191
|
+
function initializeP5TouchOverrides() {
|
|
192
|
+
// Wait for p5 to be ready
|
|
193
|
+
setTimeout(() => {
|
|
194
|
+
if (window._setupDone) {
|
|
195
|
+
overrideP5Touch();
|
|
196
|
+
} else {
|
|
197
|
+
// Try again after setup
|
|
198
|
+
const checkP5 = setInterval(() => {
|
|
199
|
+
if (window._setupDone) {
|
|
200
|
+
overrideP5Touch();
|
|
201
|
+
clearInterval(checkP5);
|
|
202
|
+
}
|
|
203
|
+
}, 100);
|
|
204
|
+
}
|
|
205
|
+
}, 100);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function overrideP5Touch() {
|
|
209
|
+
const origTouchStarted = window.touchStarted || function() {};
|
|
210
|
+
const origTouchMoved = window.touchMoved || function() {};
|
|
211
|
+
const origTouchEnded = window.touchEnded || function() {};
|
|
212
|
+
const origMousePressed = window.mousePressed || function() {};
|
|
213
|
+
const origMouseDragged = window.mouseDragged || function() {};
|
|
214
|
+
const origMouseReleased = window.mouseReleased || function() {};
|
|
215
|
+
|
|
216
|
+
// Ensure all touch functions return false
|
|
217
|
+
window.touchStarted = function(e) {
|
|
218
|
+
origTouchStarted(e);
|
|
219
|
+
return false;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
window.touchMoved = function(e) {
|
|
223
|
+
origTouchMoved(e);
|
|
224
|
+
return false;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
window.touchEnded = function(e) {
|
|
228
|
+
origTouchEnded(e);
|
|
229
|
+
return false;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
window.mousePressed = function(e) {
|
|
233
|
+
origMousePressed(e);
|
|
234
|
+
return false;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
window.mouseDragged = function(e) {
|
|
238
|
+
origMouseDragged(e);
|
|
239
|
+
return false;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
window.mouseReleased = function(e) {
|
|
243
|
+
origMouseReleased(e);
|
|
244
|
+
return false;
|
|
245
|
+
};
|
|
246
|
+
}
|