Last active
February 5, 2021 12:45
-
-
Save maninak/a0f2ebd1facd9da4feb1293963b790f7 to your computer and use it in GitHub Desktop.
Change presentation slides with a Nintendo Switch Joycon controller with the power of the web's native Gamepad API. The joycon must already be connected with your computer (pc/mac/linux) via bluetooth (hold connect button on controller until "searching" mode). Only left and right buttons implemented. Any button could easily be mapped differenly..
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// connect the left joycon to any computer via bluetooth and paste the following script in the console of a webpage | |
(() => { | |
const VENDOR_ID = '057e'; | |
const DEVICE_ID = '2006'; | |
const [LEFT_BUTTON, RIGHT_BUTTON] = [0, 3]; | |
const [LEFT_ARROW_KEY_CODE, RIGHT_ARROW_KEY_CODE] = [37, 39]; | |
let gamepadIndex, intervalID, isPressing = false; | |
function pressKey(keyCode) { | |
if (isPressing) { | |
return; | |
} | |
const activeElement = document.activeElement; | |
const targetDocument = activeElement.tagName === 'IFRAME' ? activeElement.contentDocument : document; | |
['keydown', 'keyup'].forEach(typeArg => { | |
targetDocument.body.dispatchEvent(new KeyboardEvent(typeArg, { keyCode, bubbles: true })); | |
}); | |
isPressing = true; | |
}; | |
addEventListener('gamepadconnected', e => { | |
const gamepadId = e.gamepad.id; | |
if (gamepadIndex != null || !gamepadId.includes(VENDOR_ID) || !gamepadId.includes(DEVICE_ID)) { | |
return; | |
} | |
gamepadIndex = e.gamepad.index; | |
intervalID = setInterval(() => { | |
const buttons = navigator.getGamepads()[gamepadIndex].buttons; | |
if (buttons[LEFT_BUTTON].pressed) { | |
pressKey(LEFT_ARROW_KEY_CODE); | |
return; | |
} else if (buttons[RIGHT_BUTTON].pressed) { | |
pressKey(RIGHT_ARROW_KEY_CODE); | |
return; | |
} | |
isPressing = false; | |
}, 1000 / 60); | |
}); | |
addEventListener('gamepaddisconnected', e => { | |
if (gamepadIndex === e.gamepad.index) { | |
clearInterval(intervalID); | |
gamepadIndex = intervalID = null; | |
} | |
}); | |
if (navigator.wakeLock) { | |
const requestWakeLock = (isFirstRequest) => { | |
if (document.visibilityState !== 'visible') { | |
return; | |
} | |
navigator.wakeLock.request('screen').then(() => { | |
if (isFirstRequest) { | |
document.addEventListener('visibilitychange', requestWakeLock); | |
document.addEventListener('fullscreenchange', requestWakeLock); | |
} | |
}).catch(() => {}); | |
}; | |
requestWakeLock(true); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment