setup()
setup() runs once when the page loads. It detects which browser features are available (rather than assuming), creates the canvas and UI buttons, and initializes state variables. This 'feature detection' pattern is essential for cross-platform code—never assume a device has accelerometers, camera, or audio APIs.
🔬 This pattern repeats for all five buttons with different text and callbacks. What happens if you change btnStep from 26 to 50? How will the button spacing change?
micButton = createButton('Enable Microphone');
micButton.position(btnX, btnY0 + btnStep * 1);
micButton.mousePressed(initMic);
function setup() {
createCanvas(windowWidth, windowHeight);
textFont('system-ui, sans-serif');
textSize(14);
// Detect feature support
deviceMotionSupported = 'DeviceMotionEvent' in window;
deviceOrientationSupported = 'DeviceOrientationEvent' in window;
canVibrate = 'vibrate' in navigator;
// Detect WebGL2 separately
const testCanvas = document.createElement('canvas');
hasWebGL2 = !!testCanvas.getContext('webgl2');
// Prepare WebGL graphics buffer
webglGfx = createGraphics(320, 240, WEBGL);
lastMousePos = createVector(mouseX, mouseY);
lastClickPos = createVector(-1, -1);
// Control buttons (permission-gated features)
const btnX = 20;
const btnY0 = 20;
const btnStep = 26;
micButton = createButton('Enable Microphone');
micButton.position(btnX, btnY0 + btnStep * 1);
micButton.mousePressed(initMic);
cameraButton = createButton('Enable Camera');
cameraButton.position(btnX, btnY0 + btnStep * 2);
cameraButton.mousePressed(initCamera);
motionButton = createButton('Enable Motion Sensors');
motionButton.position(btnX, btnY0 + btnStep * 3);
motionButton.mousePressed(requestMotionPermission);
hapticsButton = createButton('Test Vibration');
hapticsButton.position(btnX, btnY0 + btnStep * 4);
hapticsButton.mousePressed(doVibrate);
soundButton = createButton('Test Audio Output');
soundButton.position(btnX, btnY0 + btnStep * 5);
soundButton.mousePressed(toggleTone);
}
Line-by-line explanation (10 lines)
🔧 Subcomponents:
deviceMotionSupported = 'DeviceMotionEvent' in window;
Checks if the browser supports device motion events by testing if DeviceMotionEvent exists as a global object
const testCanvas = document.createElement('canvas');
hasWebGL2 = !!testCanvas.getContext('webgl2');
Creates a temporary canvas and attempts to get a WebGL 2 context—the !! converts the result to a boolean
micButton = createButton('Enable Microphone');
micButton.position(btnX, btnY0 + btnStep * 1);
micButton.mousePressed(initMic);
Creates interactive buttons for permission-gated features; each button is positioned vertically with spacing and linked to a callback function
createCanvas(windowWidth, windowHeight);- Creates a p5.js canvas that fills the entire browser window; windowWidth and windowHeight are p5.js variables that auto-update
textFont('system-ui, sans-serif');- Sets the font for all text to use system UI fonts, which render consistently across devices
deviceMotionSupported = 'DeviceMotionEvent' in window;- Tests if DeviceMotionEvent exists as a property of the global window object; the 'in' operator returns true if it exists, false otherwise
const testCanvas = document.createElement('canvas');- Creates a hidden DOM canvas element (not a p5.js canvas) to test for WebGL 2 capabilities
hasWebGL2 = !!testCanvas.getContext('webgl2');- Attempts to get a WebGL 2 context from the test canvas; !! converts the result (object or null) to a boolean true/false
webglGfx = createGraphics(320, 240, WEBGL);- Creates an off-screen WebGL graphics buffer (not displayed directly) with 320×240 pixels; this buffer is used to render the 3D cube
lastMousePos = createVector(mouseX, mouseY);- Creates a p5.Vector object storing the current mouse position; vectors are easier to manipulate and display than separate x,y numbers
micButton = createButton('Enable Microphone');- Creates an HTML button with the text 'Enable Microphone' that will appear on the page
micButton.position(btnX, btnY0 + btnStep * 1);- Positions the button at pixel coordinates (20, 46) on the page—btnX is 20, btnY0 is 20, btnStep is 26, so 20 + 26*1 = 46
micButton.mousePressed(initMic);- Registers the initMic() function to be called when the user clicks this button