diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b017ff2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.hintrc \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..955cc0b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "msedge", + "request": "launch", + "name": "Launch Edge against localhost", + "url": "http://localhost:8000", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/index.html b/index.html index e93dc66..3a75208 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,7 @@ - PestoLink-Online + PestoLink-Basil @@ -20,25 +20,42 @@
- -
-
Axis 0
-
127
-
- -
Axis 1
-
127
-
- -
Axis 2
-
127
-
- -
Axis 3
-
127
-
+
+
+
Axis 0
+
127
+
+ +
Axis 1
+
127
+
+ +
Axis 2
+
127
+
+ +
Axis 3
+
127
+
+
+
+
Axis 0
+
127
+
+ +
Axis 1
+
127
+
+ +
Axis 2
+
127
+
+ +
Axis 3
+
127
+
+
-
@@ -63,6 +80,12 @@
+
Dual Input
+ +
+
+
+
@@ -77,29 +100,57 @@
- -
- - - - - - - - - - - - - - - - +
+
+ + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + +

+ PestoLink Basil +
+ An all new version of PestoLink made by Kavin from team 5338 Roboloco! + Featuring: +
+ -Better keyboard controls that allow for use of all buttons(not just the first few) +
+ -Dual Controller Support to emulate FRC better +

Embedded Platform Support
PestoLink currently supports two embedded platforms, MicroPython and Arduino (designed for RP2040 on XRP Kits and ESP32 respectively). @@ -112,10 +163,10 @@

What does "Override axes with WASD" do?
By default, keyboard data is sent seperatly from axis/button data. If you would like to drive your robot using your keyboard, - you can enable this switch to override the axis/button data with keyboard input. 'WASD' wil override Axis 0 and 1, 'IJKL' will override Axis 2 and 3. - 'ZXCVBNM,' will overide buttons 0 through 7. + you can enable this switch to override the axis/button data with keyboard input. 'WASD' will override Axis 0 and Axis 1. 'IJKL' will override Axis 2 and Axis 3. + 'QERTYUOPZXCVBNM,' will override the number buttons. Currently, a way to change button maps is in progress. -

If you have any questions, feel free to reach out! (jrw4561@gmail.com) +

If you have any questions, feel free to reach out to me at 921563@lcps.org!

@@ -123,4 +174,4 @@ - \ No newline at end of file + diff --git a/index.js b/index.js index 27378f8..535dca5 100644 --- a/index.js +++ b/index.js @@ -4,10 +4,15 @@ let bleAgent = createBleAgent(); let keyboardAgent = createKeyboardAgent(); let axisAgent = createMobileAxisAgent(); let buttonAgent = createMobileButtonAgent(); -let gamepadAgent = createGamepadAgent(); +let gamepadAgent = createGamepadAgent(0); +let secondaryGamepadAgent = createGamepadAgent(1); let axisCallback = null let buttonCallback = null +let updateElementCallback = gamepadAgent.updateElements +let secondaryAxisCallback = secondaryGamepadAgent.getAxes +let secondaryButtonCallback = secondaryGamepadAgent.getButtons + let mobileElements = document.getElementsByClassName("mobile-only"); let desktopElements = document.getElementsByClassName("desktop-only"); @@ -20,9 +25,10 @@ let hackSpacerElement = document.getElementById("hack-spacer"); let toggleMobile = document.getElementById('toggle-mobile-layout'); let toggleKeyboardWASD = document.getElementById('toggle-keyboard-style'); let toggleInfo = document.getElementById('toggle-info'); +let toggleDualControllers = document.getElementById('toggle-dual-controllers') +let lastKeyPressed = 1; // --------------------------- state management ------------------------------------ // - if (localStorage.getItem(toggleMobile.id) == null) { if (isMobile) { localStorage.setItem(toggleMobile.id, 'true'); @@ -30,27 +36,30 @@ if (localStorage.getItem(toggleMobile.id) == null) { localStorage.setItem(toggleMobile.id, 'false'); } updateMobileSlider(toggleMobile, false); - } +} - if(isMobile) for (let element of helpRow) element.style.display = "none"; +if (isMobile) for (let element of helpRow) element.style.display = "none"; document.addEventListener('DOMContentLoaded', function () { - updateMobileSlider(toggleMobile, toggleState=false); - updateSlider(toggleKeyboardWASD, toggleState=false); - updateInfoSlider(toggleInfo, toggleState=false); + updateMobileSlider(toggleMobile, toggleState = false); + updateKeyboardSlider(toggleKeyboardWASD, toggleState = false); + updateInfoSlider(toggleInfo, toggleState = false); + updateDualControllerSlider(toggleDualControllers, toggleState = false); + + toggleMobile.onmousedown = updateMobileSlider.bind(null, toggleMobile, toggleState = true) + toggleKeyboardWASD.onmousedown = updateKeyboardSlider.bind(null, toggleKeyboardWASD, toggleState = true) + toggleInfo.onmousedown = updateInfoSlider.bind(null, toggleInfo, toggleState = true) + toggleDualControllers.onmousedown = updateDualControllerSlider.bind(null, toggleDualControllers, toggleState = true) + + toggleMobile.ontouchstart = updateMobileSlider.bind(null, toggleMobile, toggleState = true) + toggleKeyboardWASD.ontouchstart = updateKeyboardSlider.bind(null, toggleKeyboardWASD, toggleState = true) + toggleInfo.ontouchstart = updateInfoSlider.bind(null, toggleInfo, toggleState = true) + toggleDualControllers.ontouchstart = updateDualControllerSlider.bind(null, toggleDualControllers, toggleState = true) - toggleMobile.onmousedown = updateMobileSlider.bind(null, toggleMobile, toggleState=true) - toggleKeyboardWASD.onmousedown = updateSlider.bind(null, toggleKeyboardWASD, toggleState=true) - toggleInfo.onmousedown = updateInfoSlider.bind(null, toggleInfo, toggleState=true) - - toggleMobile.ontouchstart = updateMobileSlider.bind(null, toggleMobile, toggleState=true) - toggleKeyboardWASD.ontouchstart = updateSlider.bind(null, toggleKeyboardWASD, toggleState=true) - toggleInfo.ontouchstart = updateInfoSlider.bind(null, toggleInfo, toggleState=true) - window.setInterval(renderLoop, 100); // call renderLoop every num milliseconds }); -function updateMobileSlider(sliderElement, toggleState){ +function updateMobileSlider(sliderElement, toggleState) { updateSlider(sliderElement, toggleState); if (localStorage.getItem(toggleMobile.id) === 'true') { @@ -63,10 +72,19 @@ function updateMobileSlider(sliderElement, toggleState){ for (let element of desktopElements) element.style.display = "grid"; axisCallback = gamepadAgent.getAxes buttonCallback = gamepadAgent.getButtons + if (localStorage.getItem(toggleDualControllers.id) === 'true') { + document.getElementById("desktop-button1").style.display = "grid" + document.getElementById("desktop-axis1").style.display = "grid" + for (let element of desktopElements) element.style.height = "20rem"; + } else { + document.getElementById("desktop-button1").style.display = "none" + document.getElementById("desktop-axis1").style.display = "none" + for (let element of desktopElements) element.style.height = "30rem"; + } } } -function updateInfoSlider(sliderElement, toggleState){ +function updateInfoSlider(sliderElement, toggleState) { updateSlider(sliderElement, toggleState); if (localStorage.getItem(toggleInfo.id) === 'true') { @@ -77,50 +95,112 @@ function updateInfoSlider(sliderElement, toggleState){ hackSpacerElement.style.display = "grid"; } } - -function updateSlider(sliderElement, toggleState){ - if(toggleState){ - if ( localStorage.getItem(sliderElement.id) === 'true') { +function updateKeyboardSlider(sliderElement, toggleState) { + let buttonElements = document.querySelectorAll('[id^="0buttonDesktop"]'); + updateSlider(sliderElement, toggleState); + let keys = ['Q', 'E', 'R', 'T', 'Y', 'U', 'O', 'P', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',']; + if (localStorage.getItem(toggleKeyboardWASD.id) === 'true') { + buttonElements.forEach((button, index) => button.textContent = keys[index]); + } else { + buttonElements.forEach((button, index) => button.textContent = index); + } +} +function updateDualControllerSlider(sliderElement, toggleState) { + updateSlider(sliderElement, toggleState); + if (localStorage.getItem(toggleDualControllers.id) === 'true') { + document.getElementById("desktop-button1").style.display = "grid" + document.getElementById("desktop-axis1").style.display = "grid" + for (let element of desktopElements) element.style.height = "25rem"; + } else { + document.getElementById("desktop-button1").style.display = "none" + document.getElementById("desktop-axis1").style.display = "none" + for (let element of desktopElements) element.style.height = "30rem"; + } +} +function updateSlider(sliderElement, toggleState) { + if (toggleState) { + if (localStorage.getItem(sliderElement.id) === 'true') { localStorage.setItem(sliderElement.id, 'false'); } else { localStorage.setItem(sliderElement.id, 'true'); - } + } } - if ( localStorage.getItem(sliderElement.id) === 'true') { + if (localStorage.getItem(sliderElement.id) === 'true') { sliderElement.style.backgroundColor = 'var(--alf-green)'; - sliderElement.firstElementChild.style.transform = 'translateX(2vw)'; - sliderElement.firstElementChild.style.webkitTransform = 'translateX(2vw)'; - sliderElement.firstElementChild.style.msTransform = 'translateX(2vw)'; + sliderElement.firstElementChild.style.transform = 'translateX(2em)'; + sliderElement.firstElementChild.style.webkitTransform = 'translateX(2em)'; + sliderElement.firstElementChild.style.msTransform = 'translateX(2em)'; } else { sliderElement.style.backgroundColor = 'rgb(189, 188, 188)'; sliderElement.firstElementChild.style.transform = 'none'; - sliderElement.firstElementChild.style.webkitTransform = 'none'; + sliderElement.firstElementChild.style.webkitTransform = 'none'; sliderElement.firstElementChild.style.msTransform = 'none'; } } // ----------------------------------------- main --------------------------------------- // -function renderLoop() { +async function renderLoop() { + var axisValueElements = document.querySelectorAll('[id^="0axisValue"]'); + var barElements = document.querySelectorAll('[id^="0bar"]'); + var buttonElements = document.querySelectorAll('[id^="0buttonDesktop"]'); + updateElementCallback(); + // console.log(document.lastKeyPressed); //bytes 0: packet version //bytes 1-4: axes //bytes 5-6: button states //bytes 7-17: pressed keyboard keys - let rawPacket = new Uint8Array(1 + 4 + 2 + 11) + //byte 18: controller number + let rawPacket = new Uint8Array(1 + 4 + 2 + 11 + 1) rawPacket[0] = 0x01; //packet version + if (!(Array.from(navigator.getGamepads()).filter(gamepad => gamepad).length == 1 && localStorage.getItem(toggleDualControllers.id) === 'true' && localStorage.getItem(toggleKeyboardWASD.id) === 'true')) { + rawPacket[1] = axisCallback().axis0 + rawPacket[2] = axisCallback().axis1 + rawPacket[3] = axisCallback().axis2 + rawPacket[4] = axisCallback().axis3 - rawPacket[1] = axisCallback().axis0 - rawPacket[2] = axisCallback().axis1 - rawPacket[3] = axisCallback().axis2 - rawPacket[4] = axisCallback().axis3 - - rawPacket[5] = buttonCallback().byte0 - rawPacket[6] = buttonCallback().byte1 + rawPacket[5] = buttonCallback().byte0 + rawPacket[6] = buttonCallback().byte1 + } + else{ + rawPacket[1] = 127 + rawPacket[2] = 127 + rawPacket[3] = 127 + rawPacket[4] = 127 + } + rawPacket[18] = 0 keyboardArray = keyboardAgent.getKeyboardArray() + var keys = { + //Change these to change which keys are bound to which button. + 'axis0+': 22, + 'axis0-': 19, + 'axis1+': 37, + 'axis1-': 41, + 'axis2+': 30, + 'axis2-': 28, + 'axis3+': 29, + 'axis3-': 27, + 'button0': 35, + 'button1': 23, + 'button2': 36, + 'button3': 38, + 'button4': 43, + 'button5': 39, + 'button6': 33, + 'button7': 34, + 'button8': 44, + 'button9': 42, + 'button10': 21, + 'button11': 40, + 'button12': 20, + 'button13': 32, + 'button14': 31, + 'button15': 4 + } for (let i = 0; i < 12; i++) { if (keyboardArray.length > i) { @@ -134,34 +214,96 @@ function renderLoop() { if (localStorage.getItem(toggleKeyboardWASD.id) === 'true') { for (let key of keyboardArray) { - // WASD for axis 0 and 1 - if (key === keyToNum["KeyA"]) rawPacket[1] = clampUint8(rawPacket[1] - 128); - if (key === keyToNum["KeyD"]) rawPacket[1] = clampUint8(rawPacket[1] + 128); - if (key === keyToNum["KeyW"]) rawPacket[2] = clampUint8(rawPacket[2] - 128); - if (key === keyToNum["KeyS"]) rawPacket[2] = clampUint8(rawPacket[2] + 128); - - // IJKL for axis 2 and 3 - if (key === keyToNum["KeyJ"]) rawPacket[3] = clampUint8(rawPacket[3] - 128); - if (key === keyToNum["KeyL"]) rawPacket[3] = clampUint8(rawPacket[3] + 128); - if (key === keyToNum["KeyI"]) rawPacket[4] = clampUint8(rawPacket[4] - 128); - if (key === keyToNum["KeyK"]) rawPacket[4] = clampUint8(rawPacket[4] + 128); - - // override buttons - if (key === keyToNum["KeyZ"]) rawPacket[5] |= (1 << 0); - if (key === keyToNum["KeyX"]) rawPacket[5] |= (1 << 1); - if (key === keyToNum["KeyC"]) rawPacket[5] |= (1 << 2); - if (key === keyToNum["KeyV"]) rawPacket[5] |= (1 << 3); - if (key === keyToNum["KeyB"]) rawPacket[5] |= (1 << 4); - if (key === keyToNum["KeyN"]) rawPacket[5] |= (1 << 5); - if (key === keyToNum["KeyM"]) rawPacket[5] |= (1 << 6); - if (key === keyToNum["Comma"]) rawPacket[5] |= (1 << 7); + // console.log(this); + if (key === keys['axis0-']) rawPacket[1] = clampUint8(rawPacket[1] - 128); //A + if (key === keys['axis0+']) rawPacket[1] = clampUint8(rawPacket[1] + 128); //D + if (key === keys['axis1-']) rawPacket[2] = clampUint8(rawPacket[2] - 128); //W + if (key === keys['axis1+']) rawPacket[2] = clampUint8(rawPacket[2] + 128); //S + if (key === keys['axis2-']) rawPacket[3] = clampUint8(rawPacket[3] - 128); //J + if (key === keys['axis2+']) rawPacket[3] = clampUint8(rawPacket[3] + 128); //L + if (key === keys['axis3-']) rawPacket[4] = clampUint8(rawPacket[4] - 128); //I + if (key === keys['axis3+']) rawPacket[4] = clampUint8(rawPacket[4] + 128); //K + for (let i = 0; i < 8; i++) { + if (key === keys['button' + i]) rawPacket[5] |= (1 << i) + } + for (let i = 8; i < 16; i++) { + if (key === keys['button' + i]) rawPacket[6] |= (1 << i - 8) + } } } - if (!document.hasFocus()) { rawPacket.fill(0, 0, 20); } + if (!document.hasFocus()) { rawPacket.fill(0, 7, 20); } + + if (localStorage.getItem(toggleKeyboardWASD.id) === 'true') { + for (let i = 0; i < 4; i++) { + let axisValGamepad = rawPacket[i + 1]; + axisValueElements[i].textContent = axisValGamepad + let percentage = Math.round(axisValGamepad * 100 / 255); + barElements[i].style.background = `linear-gradient(to right, var(--alf-green) ${percentage}%, grey 0%)`; + } + if (Array.from(navigator.getGamepads()).filter(gamepad => gamepad).length < 1 || (Array.from(navigator.getGamepads()).filter(gamepad => gamepad).length == 1 && localStorage.getItem(toggleDualControllers.id) === 'true' && localStorage.getItem(toggleKeyboardWASD.id) === 'true')) buttonElements.forEach((button) => button.style.background = 'grey'); + if (rawPacket[5] != 0 || rawPacket[6] != 0) { + for (let i = 7; rawPacket[i] != 0; i++) { + if (Object.values(keys).slice(8).includes(rawPacket[i])) { + buttonElements[Object.values(keys).slice(8).indexOf(rawPacket[i])].style.background = 'var(--alf-green)'; + } + // if(rawPacket[i]<=14){ + // buttonElements[rawPacket[i]-5].style.background = 'var(--alf-green)'; + // } + // else if(rawPacket[i]===35){ + // buttonElements[10].style.background = 'var(--alf-green)'; + // } + // else if(rawPacket[i]===23){ + // buttonElements[11].style.background = 'var(--alf-green)'; + // } + // else if(rawPacket[i]===36){ + // buttonElements[12].style.background = 'var(--alf-green)'; + // } + // else if(rawPacket[i]===38){ + // buttonElements[13].style.background = 'var(--alf-green)'; + // } + // else if(rawPacket[i]===43){ + // buttonElements[14].style.background = 'var(--alf-green)'; + // } + // else if(rawPacket[i]===39){ + // buttonElements[15].style.background = 'var(--alf-green)'; + // } + } + } + } + + // console.log(rawPacket) + + await bleAgent.attemptSend(rawPacket); + if (localStorage.getItem(toggleDualControllers.id) === 'true') { + let rawPacket2 = new Uint8Array(1 + 4 + 2 + 11 + 1) + if ((Array.from(navigator.getGamepads()).filter(gamepad => gamepad).length == 1 && localStorage.getItem(toggleKeyboardWASD.id) === 'true')) { + rawPacket2[0] = 0x01; //packet version + + rawPacket2[1] = axisCallback().axis0 + rawPacket2[2] = axisCallback().axis1 + rawPacket2[3] = axisCallback().axis2 + rawPacket2[4] = axisCallback().axis3 + + rawPacket2[5] = buttonCallback().byte0 + rawPacket2[6] = buttonCallback().byte1 + rawPacket2[18] = 1; + } + else { + rawPacket2[0] = 0x01; //packet version - //console.log(rawPacket) - bleAgent.attemptSend(rawPacket); + rawPacket2[1] = secondaryAxisCallback().axis0 + rawPacket2[2] = secondaryAxisCallback().axis1 + rawPacket2[3] = secondaryAxisCallback().axis2 + rawPacket2[4] = secondaryAxisCallback().axis3 + + rawPacket2[5] = secondaryButtonCallback().byte0 + rawPacket2[6] = secondaryButtonCallback().byte1 + rawPacket2[18] = 1; + } + // console.log(rawPacket2); + await bleAgent.attemptSend(rawPacket2); + } } // -------------------------------------------- bluetooth --------------------------------------- // @@ -175,7 +317,7 @@ function createBleAgent() { const CHARACTERISTIC_UUID_GAMEPAD = '452af57e-ad27-422c-88ae-76805ea641a9'; const CHARACTERISTIC_UUID_TELEMETRY = '266d9d74-3e10-4fcd-88d2-cb63b5324d0c'; - if (isMobile){ + if (isMobile) { buttonBLE.ontouchend = updateBLE; } else { buttonBLE.onclick = updateBLE; @@ -206,7 +348,7 @@ function createBleAgent() { async function connectBLE() { try { - if (device == null){ + if (device == null) { displayBleStatus('Connecting', 'black'); device = await navigator.bluetooth.requestDevice({ filters: [{ services: [SERVICE_UUID_PESTOBLE] }] }); } else { @@ -215,7 +357,7 @@ function createBleAgent() { server = await device.gatt.connect(); service = await server.getPrimaryService(SERVICE_UUID_PESTOBLE); - + characteristic_gamepad = await service.getCharacteristic(CHARACTERISTIC_UUID_GAMEPAD); try{ characteristic_telemetry = await service.getCharacteristic(CHARACTERISTIC_UUID_TELEMETRY); @@ -237,7 +379,7 @@ function createBleAgent() { } else if (error.name === 'SecurityError') { displayBleStatus('Security error', '#eb5b5b'); } else { - console.log( error); + console.log(error); displayBleStatus('Connection failed', '#eb5b5b'); connectBLE(); } @@ -313,7 +455,7 @@ function createBleAgent() { // Function to start or reset the watchdog timer function batteryWatchdogReset() { displayBleStatus('Connected', '#4dae50'); //green - if (timer) {clearTimeout(timer);} + if (timer) { clearTimeout(timer); } timer = setTimeout(() => { displayBleStatus('timeout?', 'black'); }, timeout); @@ -321,7 +463,7 @@ function createBleAgent() { // Function to stop the watchdog timer function batteryWatchdogStop() { batteryWatchdogReset() - if (timer) {clearTimeout(timer);timer = null;} + if (timer) { clearTimeout(timer); timer = null; } } return { @@ -484,20 +626,25 @@ function createMobileButtonAgent() { // -------------------------------------------- desktop --------------------------------------- // -function createGamepadAgent() { +function createGamepadAgent(gamepadNum) { function getGamepads() { return Array.from(navigator.getGamepads()).filter(gamepad => gamepad); } function getSelectedGamepad() { - return getGamepads().find(gamepad => gamepad.index == 0); + return getGamepads().find(gamepad => gamepad.index == gamepadNum); } + var axisValueElements = document.querySelectorAll('[id^="' + gamepadNum + 'axisValue"]'); + var barElements = document.querySelectorAll('[id^="' + gamepadNum + 'bar"]'); + var buttonElements = document.querySelectorAll('[id^="' + gamepadNum + 'buttonDesktop"]'); - var axisValueElements = document.querySelectorAll('[id^="axisValue"]'); - var barElements = document.querySelectorAll('[id^="bar"]'); - var buttonElements = document.querySelectorAll('[id^="buttonDesktop"]'); - + function updateElementLists(newID){ + let documentID = (Array.from(navigator.getGamepads()).filter(gamepad => gamepad).length == 1 && localStorage.getItem(toggleDualControllers.id) === 'true' && localStorage.getItem(toggleKeyboardWASD.id) === 'true') ? 1 : gamepadNum; + axisValueElements = document.querySelectorAll('[id^="' + documentID + 'axisValue"]'); + barElements = document.querySelectorAll('[id^="' + documentID + 'bar"]'); + buttonElements = document.querySelectorAll('[id^="' + documentID + 'buttonDesktop"]'); + } function convertUnitFloatToByte(unitFloat) { let byte = 127 if (unitFloat != 0) byte = Math.round((unitFloat + 1) * (255 / 2)); @@ -531,6 +678,7 @@ function createGamepadAgent() { if (gamepad.buttons[i].pressed) { firstByte |= (gamepad.buttons[i].pressed << i); buttonElements[i].style.background = 'var(--alf-green)'; + } else { buttonElements[i].style.background = 'grey'; } @@ -551,23 +699,24 @@ function createGamepadAgent() { return { getAxes: getGamepadAxes, - getButtons: getButtonBytes + getButtons: getButtonBytes, + updateElements: updateElementLists } } // -------------------------------------------- keyboard --------------------------------------- // function createKeyboardAgent() { - document.addEventListener('keydown', handleKeyboardInput); document.addEventListener('keyup', handleKeyboardInput); function handleKeyboardInput(event) { if (event.repeat != true) { keyEventQueue.push(event); + this.lastKeyPressed = event.code; } } - + // this.console.log(this); var keyEventQueue = []; var keyboardState = []; diff --git a/styles.css b/styles.css index 8079ba2..8c217d5 100644 --- a/styles.css +++ b/styles.css @@ -34,15 +34,14 @@ body { flex-direction: column; width: 100vw; height: 100vh; - overscroll-behavior-y: none; } .container { display: flex; box-sizing: border-box; - margin: 0.5vw; + margin: 0.5rem; background: var(--alf-beige); - border-radius: 2vw; + border-radius: 1rem; } .desktop-only, @@ -54,20 +53,20 @@ body { display: none; box-sizing: border-box; background: grey; - width: 84vw; - margin: 1vw; - padding: 0.5vw; - padding-left: 2vw; - border-radius: 2vw; - font-size: 1vw; + width: 84em; + margin: 1rem; + padding: 0.5em; + padding-left: 2em; + border-radius: 2rem; + font-size: small; } #hack-spacer { display: grid; background: var(--alf-green); - width: 84vw; - margin: 1vw; - height: 6vw; + width: 84em; + margin: 1rem; + height: 6em; } #user-container { @@ -81,9 +80,11 @@ body { #mobile-button, #mobile-joystick, #desktop-axis, -#desktop-button { - width: 30vw; - height: 30vw; +#desktop-button, +#desktop-axis1, +#desktop-button1 { + width:30rem; + height: 30rem; display: none; } @@ -95,43 +96,44 @@ body { #mobile-button { display: grid; grid-template-columns: repeat(3, 1fr); - padding: 2vw; + padding: 2em; } #joystick-background { - border-radius: 1vw; + border-radius: 1em; background: white; display: flex; justify-content: center; align-items: center; - width: 14vw; - height: 14vw; + width: 14em; + height: 14em; } .joystick { background: grey; border-radius: 50%; + -webkit-user-select: none; user-select: none; -webkit-user-select: none; cursor: pointer; - height: 13vw; - width: 13vw; + height: 13em; + width: 13em; } #interface { - width: 22vw; - height: 30vw; + width: 20em; + height: 30em; display: grid; grid-template-rows: 1fr 1fr 2fr; grid-template-columns: 1fr 1fr; - grid-gap: 1vw; - padding: 1vw; + grid-gap: 1em; + padding: 1em; } #ble-button { background-color: rgb(189, 188, 188); - border-radius: 1vw; - font-size: 4vw; + border-radius: 1rem; + font-size: 4em; grid-row: 1; grid-column: 1; cursor: pointer; @@ -154,16 +156,16 @@ body { background-color: grey; color: white; overflow: hidden; - border-radius: 1vw; - width: 12vw; - font-size: 2vw; + border-radius: 1rem; + width: 10rem; + font-size: 2em; grid-row: 1; grid-column: 2; } #ble-status { background-color: black; - font-size: 2vw; + font-size: 2em; grid-row: 2; grid-column: 1; grid-column: span 2; @@ -171,7 +173,7 @@ body { #mobile-button button { - font-size: 5vw; + font-size: 5em; background-color: grey; transform: scale(1.3); border-radius: 100%; @@ -181,57 +183,61 @@ body { align-items: center; } -#desktop-button { +#desktop-button, +#desktop-button1{ display: grid; - padding: 1vw; - grid-gap: 0.5vw; + padding: 1em; + grid-gap: 0.5em; grid-template-rows: 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr; } -#desktop-button button { - font-size: 2vw; +#desktop-button button, +#desktop-button1 button { + font-size: 2em; background: grey; border: none; - border-radius: 1vw; + border-radius: 1rem; } -#desktop-axis { +#desktop-axis, +#desktop-axis1 { display: grid; - padding: 1vw; - grid-row-gap: 1vw; - grid-column-gap: 0.5vw; + padding: 1rem; + grid-row-gap: 1rem; + grid-column-gap: 0.5rem; grid-template-rows: 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr; } -#desktop-axis div { - font-size: 2vw; +#desktop-axis, +#desktop-axis1 div { + font-size: 2rem; border: none; } .slider-non { background-color: grey; - border-radius: 1vw; + border-radius: 1rem; display: flex; justify-content: center; align-items: center; } .slider-bar { - border-radius: 1vw; - width: 12vw; + border-radius: 1rem; + width: 13rem; background: rgb(141, 168, 204); } #settings-grid { display: grid; - padding: 0.5vw; - grid-column-gap: 0.5vw; + padding: 0.25rem; + grid-column-gap: 0.5em; grid-template-columns: 2fr 1fr; grid-column: span 2; background-color: grey; - border-radius: 1vw; + border-radius: 1em; justify-content: center; align-items: center; text-align: center; @@ -242,14 +248,14 @@ body { justify-content: center; align-items: center; text-align: center; - font-size: 1.2vw; + font-size: 1.2rem; } .settings-toggle { position: relative; display: inline-block; - width: 5vw; - height: 3vw; + width: 5em; + height: 3em; touch-action: manipulation; } @@ -261,16 +267,16 @@ body { right: 0; bottom: 0; background-color: rgb(189, 188, 188); - border-radius: 3vw; + border-radius: 3rem; } .toggle-nub { position: absolute; content: ""; - height: 2vw; - width: 2vw; - left: 0.5vw; - bottom: 0.5vw; + height: 2em; + width: 2em; + left: 0.5em; + bottom: 0.5em; background-color: white; border-radius: 50%; } \ No newline at end of file