Better touch controls.

This commit is contained in:
Sergiotarxz 2023-03-25 23:54:02 +01:00
parent 2bbb566c42
commit a2648ccadf
3 changed files with 54 additions and 67 deletions

View File

@ -8,6 +8,10 @@ export interface OverlayControlsProps {
webSocket: WebSocket | null;
};
interface ControlMap {
[id: string]: {key: number, ref: React.RefObject<HTMLAnchorElement>, sym: string, classes: string, transformX?: number, transformY?: number}
};
export default function OverlayControls({firstMenuElement, setHiddenMenu, webSocket}: OverlayControlsProps) {
function showOverlayMenu() {
setHiddenMenu(false);
@ -37,7 +41,7 @@ export default function OverlayControls({firstMenuElement, setHiddenMenu, webSoc
sendKeyDown(webSocket, false, key);
}
const controls: {[id: string]: {key: number, ref: React.RefObject<HTMLAnchorElement>, sym: string, classes: string, transformX?: number, transformY?: number}} = {};
const controls: ControlMap = {};
controls.a = {
ref: React.useRef<HTMLAnchorElement|null>(null),
key: 0,
@ -78,6 +82,37 @@ export default function OverlayControls({firstMenuElement, setHiddenMenu, webSoc
transformX: 200,
classes: 'control-right control control-pad-button',
}
function determineKey(e: React.TouchEvent<HTMLDivElement>, touch: React.Touch): number | null {
const x = touch.pageX;
const y = touch.pageY;
for (const control of Object.keys(controls)) {
const ref = controls[control].ref.current;
if (ref == null) {
console.log('No ref found');
continue;
}
let top = ref.getBoundingClientRect().top + document.documentElement.scrollTop;
const currentControl = controls[control];
const transformX = currentControl.transformX;
const transformY = currentControl.transformY;
let offsetLeft = ref.offsetLeft;
const offsetWidth = ref.offsetWidth;
let offsetTop = top;
const offsetHeight = ref.offsetHeight;
if (transformX != null) {
offsetLeft += offsetWidth * (transformX / 100);
}
if (transformY != null) {
offsetTop += offsetHeight * (transformY / 100);
}
console.log(x, y, offsetLeft, offsetTop, offsetWidth, offsetHeight);
if (x >= offsetLeft && x <= offsetLeft + offsetWidth && y >= offsetTop && y <= offsetTop + offsetHeight) {
return controls[control].key;
}
}
return null;
}
function touchStartControls(e: React.TouchEvent<HTMLDivElement>) {
e.preventDefault();
if (webSocket == null) {
@ -86,38 +121,7 @@ export default function OverlayControls({firstMenuElement, setHiddenMenu, webSoc
}
for (let i = 0; i < e.changedTouches.length; i++) {
const touch = e.changedTouches[i];
const x = touch.pageX;
const y = touch.pageY;
let key: number|null = null;
for (const control of Object.keys(controls)) {
const ref = controls[control].ref.current;
if (ref == null) {
console.log('No ref found');
continue;
}
let top = ref.getBoundingClientRect().top + document.documentElement.scrollTop;
const currentControl = controls[control];
const transformX = currentControl.transformX;
const transformY = currentControl.transformY;
let offsetLeft = ref.offsetLeft;
const offsetWidth = ref.offsetWidth;
let offsetTop = top;
const offsetHeight = ref.offsetHeight;
if (transformX != null) {
offsetLeft += offsetWidth * (transformX / 100);
}
if (transformY != null) {
offsetTop += offsetHeight * (transformY / 100);
}
console.log(x, y, offsetLeft, offsetTop, offsetWidth, offsetHeight);
if (x >= offsetLeft && x <= offsetLeft + offsetWidth && y >= offsetTop && y <= offsetTop + offsetHeight) {
key = controls[control].key;
console.log(key);
break;
}
}
console.log(key);
let key: number|null = determineKey(e, touch);
if (key == null) {
continue;
}
@ -135,44 +139,15 @@ export default function OverlayControls({firstMenuElement, setHiddenMenu, webSoc
}
for (let i = 0; i < e.changedTouches.length; i++) {
const touch = e.changedTouches[i];
const x = touch.pageX;
const y = touch.pageY;
let key: number|null = null;
for (const control of Object.keys(controls)) {
const ref = controls[control].ref.current;
if (ref == null) {
console.log('No ref found');
continue;
}
let top = ref.getBoundingClientRect().top + document.documentElement.scrollTop;
const currentControl = controls[control];
const transformX = currentControl.transformX;
const transformY = currentControl.transformY;
let offsetLeft = ref.offsetLeft;
const offsetWidth = ref.offsetWidth;
let offsetTop = top;
const offsetHeight = ref.offsetHeight;
if (transformX != null) {
offsetLeft += offsetWidth * (transformX / 100);
}
if (transformY != null) {
offsetTop += offsetHeight * (transformY / 100);
}
if (x >= offsetLeft && x <= offsetLeft + offsetWidth && y >= offsetTop && y <= offsetTop + offsetHeight) {
key = controls[control].key;
console.log(key);
break;
}
}
let key: number|null = determineKey(e, touch);
const idx = touch.identifier;
if (key == null) {
continue;
}
if (onGoingTouches[idx] != null) {
sendKeyDown(webSocket, false, onGoingTouches[idx]);
delete onGoingTouches[idx];
}
if (key == null) {
continue;
}
onGoingTouches[idx] = key;
sendKeyDown(webSocket, true, key);
}

View File

@ -169,3 +169,15 @@ form label, form input {
z-index: 4;
font-size: 20px;
}
@media (min-aspect-ratio: 176/241) {
.overlay > div.vertical-padding {
height: 0%;
}
.overlay > div.controls {
height: 100%;
}
.full-height {
height: 100vh;
}
}

File diff suppressed because one or more lines are too long