From 3d20e94a755c0b47bdc9d23b59022c4b1ce099f3 Mon Sep 17 00:00:00 2001 From: Sergiotarxz Date: Sun, 26 Mar 2023 01:00:27 +0100 Subject: [PATCH] Finishing touch interface. --- js-src/components/overlay-controls.tsx | 35 +++++++++++++++--- public/css/styles.css | 50 +++++++++++++++++++++++--- public/js/bundle.js | 2 +- 3 files changed, 78 insertions(+), 9 deletions(-) diff --git a/js-src/components/overlay-controls.tsx b/js-src/components/overlay-controls.tsx index 9110566..90da8ce 100644 --- a/js-src/components/overlay-controls.tsx +++ b/js-src/components/overlay-controls.tsx @@ -46,15 +46,42 @@ export default function OverlayControls({firstMenuElement, setHiddenMenu, webSoc ref: React.useRef(null), key: 0, sym: 'A', - classes: 'control-a control control-button', - } + classes: 'control-a control-button-a-b control control-button', + }; controls.b = { ref: React.useRef(null), key: 1, sym: 'B', transformX: 50, - classes: 'control-b control control-button', - } + classes: 'control-b control-button-a-b control control-button', + }; + controls.l = { + key: 2, + sym: 'L', + classes: 'control-l control-button-l-r control', + ref: React.useRef(null), + }; + + controls.r = { + key: 3, + sym: 'R', + classes: 'control-r control-button-l-r control', + ref: React.useRef(null), + }; + controls.start = { + ref: React.useRef(null), + key: 4, + sym: 'START', + classes: 'control-start control-button-start-select control', + transformX: 25, + }; + controls.select = { + ref: React.useRef(null), + key: 5, + sym: 'SEL', + classes: 'control-select control-button-start-select control', + transformX: -25, + }; controls.up = { ref: React.useRef(null), key: 6, diff --git a/public/css/styles.css b/public/css/styles.css index 235316f..4b0fa46 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -95,7 +95,11 @@ form label, form input { } .control-button { - border-radius: 50%; + border-radius: 50%; +} + +.control-button-a-b { + top: 50%; } .control-pad-button { @@ -104,13 +108,11 @@ form label, form input { } .control-a { - top: 50%; right: 10px;; left: unset; } .control-b { - top: 50%; transform: translateY(50%); right: 75px; left: unset; @@ -141,7 +143,7 @@ form label, form input { width: 70%; } .overlay > div.controls > a.gear { - top: 0; + top: 10px; left: 50%; transform: translate(-50%, 0); width: 60px; @@ -170,6 +172,35 @@ form label, form input { font-size: 20px; } +.overlay > div.controls > a.control-button-l-r { + width: 100px; + left: 10px; + top: 10px; +} + +.overlay > div.controls > a.control-r { + left: unset; + right: 10px; +} + +.overlay > div.controls > a.control-button-start-select { + top: calc(50% + 40px + 20px); + height: 20px; + border-radius: 40%; + font-size: 11px; + line-height: 20px; +} + +.overlay > div.controls > a.control-start { + left: 50%; + transform: translateX(25%); +} + +.overlay > div.controls > a.control-select { + right: 50%; + transform: translateX(-25%); +} + @media (min-aspect-ratio: 176/241) { .overlay > div.vertical-padding { height: 0%; @@ -180,4 +211,15 @@ form label, form input { .full-height { height: 100vh; } + + .control-pad-button { + top: 75%; + } + + .control-button-a-b { + top: 75%; + } + .overlay > div.controls > a.control-button-start-select { + top: calc(75% + 40px + 20px); + } } diff --git a/public/js/bundle.js b/public/js/bundle.js index 4c80f4d..303a324 100644 --- a/public/js/bundle.js +++ b/public/js/bundle.js @@ -126,7 +126,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \************************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ OverlayControls)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../constants */ \"./js-src/constants.ts\");\n/* harmony import */ var _packet__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../packet */ \"./js-src/packet.ts\");\n\n\n\n;\n;\nfunction OverlayControls({ firstMenuElement, setHiddenMenu, webSocket }) {\n function showOverlayMenu() {\n setHiddenMenu(false);\n setTimeout(() => {\n if (firstMenuElement.current == null) {\n return;\n }\n firstMenuElement.current.focus();\n }, 100);\n }\n const [onGoingTouches, setOnGoingTouches] = react__WEBPACK_IMPORTED_MODULE_0__.useState({});\n function mouseDown(e, key) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, true, key);\n }\n function mouseUp(e, key) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, false, key);\n }\n const controls = {};\n controls.a = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 0,\n sym: 'A',\n classes: 'control-a control control-button',\n };\n controls.b = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 1,\n sym: 'B',\n transformX: 50,\n classes: 'control-b control control-button',\n };\n controls.up = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 6,\n sym: '^',\n transformX: 100,\n classes: 'control-up control control-pad-button',\n };\n controls.down = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 7,\n sym: 'v',\n transformX: 100,\n classes: 'control-down control control-pad-button',\n };\n controls.left = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 8,\n sym: '<',\n classes: 'control-left control control-pad-button',\n };\n controls.right = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 9,\n sym: '>',\n transformX: 200,\n classes: 'control-right control control-pad-button',\n };\n function determineKey(e, touch) {\n const x = touch.pageX;\n const y = touch.pageY;\n for (const control of Object.keys(controls)) {\n const ref = controls[control].ref.current;\n if (ref == null) {\n console.log('No ref found');\n continue;\n }\n let top = ref.getBoundingClientRect().top + document.documentElement.scrollTop;\n const currentControl = controls[control];\n const transformX = currentControl.transformX;\n const transformY = currentControl.transformY;\n let offsetLeft = ref.offsetLeft;\n const offsetWidth = ref.offsetWidth;\n let offsetTop = top;\n const offsetHeight = ref.offsetHeight;\n if (transformX != null) {\n offsetLeft += offsetWidth * (transformX / 100);\n }\n if (transformY != null) {\n offsetTop += offsetHeight * (transformY / 100);\n }\n console.log(x, y, offsetLeft, offsetTop, offsetWidth, offsetHeight);\n if (x >= offsetLeft && x <= offsetLeft + offsetWidth && y >= offsetTop && y <= offsetTop + offsetHeight) {\n return controls[control].key;\n }\n }\n return null;\n }\n function touchStartControls(e) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n for (let i = 0; i < e.changedTouches.length; i++) {\n const touch = e.changedTouches[i];\n let key = determineKey(e, touch);\n if (key == null) {\n continue;\n }\n const idx = touch.identifier;\n onGoingTouches[idx] = key;\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, true, key);\n }\n return false;\n }\n function touchMoveControls(e) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n for (let i = 0; i < e.changedTouches.length; i++) {\n const touch = e.changedTouches[i];\n let key = determineKey(e, touch);\n const idx = touch.identifier;\n if (key == null) {\n continue;\n }\n if (onGoingTouches[idx] != null) {\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, false, onGoingTouches[idx]);\n delete onGoingTouches[idx];\n }\n onGoingTouches[idx] = key;\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, true, key);\n }\n return false;\n }\n function touchEndControls(e) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n for (let i = 0; i < e.changedTouches.length; i++) {\n const touch = e.changedTouches[i];\n const idx = touch.identifier;\n if (onGoingTouches[idx] == null) {\n return;\n }\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, false, onGoingTouches[idx]);\n delete onGoingTouches[idx];\n }\n return false;\n }\n document.onselectstart = () => false;\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"vertical-padding\" }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"controls\", onTouchStart: touchStartControls, onTouchMove: touchMoveControls, onTouchEnd: touchEndControls },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { tabIndex: -1, className: \"gear control\", onClick: showOverlayMenu, onTouchStart: showOverlayMenu },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: _constants__WEBPACK_IMPORTED_MODULE_1__.HOME_BUTTON_IMAGE, alt: \"Go to menu. (House icon)\" })),\n Object.keys(controls).map((key) => react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { tabIndex: -1, className: controls[key].classes, ref: controls[key].ref, key: key, onMouseDown: (e) => mouseDown(e, controls[key].key), onMouseUp: (e) => mouseUp(e, controls[key].key) }, controls[key].sym)))));\n}\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/components/overlay-controls.tsx?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ OverlayControls)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../constants */ \"./js-src/constants.ts\");\n/* harmony import */ var _packet__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../packet */ \"./js-src/packet.ts\");\n\n\n\n;\n;\nfunction OverlayControls({ firstMenuElement, setHiddenMenu, webSocket }) {\n function showOverlayMenu() {\n setHiddenMenu(false);\n setTimeout(() => {\n if (firstMenuElement.current == null) {\n return;\n }\n firstMenuElement.current.focus();\n }, 100);\n }\n const [onGoingTouches, setOnGoingTouches] = react__WEBPACK_IMPORTED_MODULE_0__.useState({});\n function mouseDown(e, key) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, true, key);\n }\n function mouseUp(e, key) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, false, key);\n }\n const controls = {};\n controls.a = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 0,\n sym: 'A',\n classes: 'control-a control-button-a-b control control-button',\n };\n controls.b = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 1,\n sym: 'B',\n transformX: 50,\n classes: 'control-b control-button-a-b control control-button',\n };\n controls.l = {\n key: 2,\n sym: 'L',\n classes: 'control-l control-button-l-r control',\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n };\n controls.r = {\n key: 3,\n sym: 'R',\n classes: 'control-r control-button-l-r control',\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n };\n controls.start = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 4,\n sym: 'START',\n classes: 'control-start control-button-start-select control',\n transformX: 25,\n };\n controls.select = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 5,\n sym: 'SEL',\n classes: 'control-select control-button-start-select control',\n transformX: -25,\n };\n controls.up = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 6,\n sym: '^',\n transformX: 100,\n classes: 'control-up control control-pad-button',\n };\n controls.down = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 7,\n sym: 'v',\n transformX: 100,\n classes: 'control-down control control-pad-button',\n };\n controls.left = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 8,\n sym: '<',\n classes: 'control-left control control-pad-button',\n };\n controls.right = {\n ref: react__WEBPACK_IMPORTED_MODULE_0__.useRef(null),\n key: 9,\n sym: '>',\n transformX: 200,\n classes: 'control-right control control-pad-button',\n };\n function determineKey(e, touch) {\n const x = touch.pageX;\n const y = touch.pageY;\n for (const control of Object.keys(controls)) {\n const ref = controls[control].ref.current;\n if (ref == null) {\n console.log('No ref found');\n continue;\n }\n let top = ref.getBoundingClientRect().top + document.documentElement.scrollTop;\n const currentControl = controls[control];\n const transformX = currentControl.transformX;\n const transformY = currentControl.transformY;\n let offsetLeft = ref.offsetLeft;\n const offsetWidth = ref.offsetWidth;\n let offsetTop = top;\n const offsetHeight = ref.offsetHeight;\n if (transformX != null) {\n offsetLeft += offsetWidth * (transformX / 100);\n }\n if (transformY != null) {\n offsetTop += offsetHeight * (transformY / 100);\n }\n console.log(x, y, offsetLeft, offsetTop, offsetWidth, offsetHeight);\n if (x >= offsetLeft && x <= offsetLeft + offsetWidth && y >= offsetTop && y <= offsetTop + offsetHeight) {\n return controls[control].key;\n }\n }\n return null;\n }\n function touchStartControls(e) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n for (let i = 0; i < e.changedTouches.length; i++) {\n const touch = e.changedTouches[i];\n let key = determineKey(e, touch);\n if (key == null) {\n continue;\n }\n const idx = touch.identifier;\n onGoingTouches[idx] = key;\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, true, key);\n }\n return false;\n }\n function touchMoveControls(e) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n for (let i = 0; i < e.changedTouches.length; i++) {\n const touch = e.changedTouches[i];\n let key = determineKey(e, touch);\n const idx = touch.identifier;\n if (key == null) {\n continue;\n }\n if (onGoingTouches[idx] != null) {\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, false, onGoingTouches[idx]);\n delete onGoingTouches[idx];\n }\n onGoingTouches[idx] = key;\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, true, key);\n }\n return false;\n }\n function touchEndControls(e) {\n e.preventDefault();\n if (webSocket == null) {\n console.log('There is not websocket');\n return;\n }\n for (let i = 0; i < e.changedTouches.length; i++) {\n const touch = e.changedTouches[i];\n const idx = touch.identifier;\n if (onGoingTouches[idx] == null) {\n return;\n }\n (0,_packet__WEBPACK_IMPORTED_MODULE_2__.sendKeyDown)(webSocket, false, onGoingTouches[idx]);\n delete onGoingTouches[idx];\n }\n return false;\n }\n document.onselectstart = () => false;\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"vertical-padding\" }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"controls\", onTouchStart: touchStartControls, onTouchMove: touchMoveControls, onTouchEnd: touchEndControls },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { tabIndex: -1, className: \"gear control\", onClick: showOverlayMenu, onTouchStart: showOverlayMenu },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: _constants__WEBPACK_IMPORTED_MODULE_1__.HOME_BUTTON_IMAGE, alt: \"Go to menu. (House icon)\" })),\n Object.keys(controls).map((key) => react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { tabIndex: -1, className: controls[key].classes, ref: controls[key].ref, key: key, onMouseDown: (e) => mouseDown(e, controls[key].key), onMouseUp: (e) => mouseUp(e, controls[key].key) }, controls[key].sym)))));\n}\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/components/overlay-controls.tsx?"); /***/ }),