From fecec13869b6d6c133a248da7e372f526e3974ae Mon Sep 17 00:00:00 2001 From: Unrud Date: Mon, 21 Feb 2022 22:30:20 +0100 Subject: [PATCH] Add hardware mouse support --- webdata/fn.js | 89 +++++++++++++++++++++++++++++++++++++++++++++- webdata/index.html | 3 ++ webdata/main.css | 6 ++-- 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/webdata/fn.js b/webdata/fn.js index d1582ff..1eba04a 100644 --- a/webdata/fn.js +++ b/webdata/fn.js @@ -67,6 +67,7 @@ var scrollYSum = 0; var dragging = false; var draggingTimeout = null; var scrolling = false; +var mouseButtons = 0; function fullscreenEnabled() { return (document.fullscreenEnabled || @@ -108,6 +109,36 @@ function fullscreenElement() { null); } +function requestPointerLock(element) { + if (element.requestPointerLock) { + element.requestPointerLock(); + } else if (element.mozRequestPointerLock) { + element.mozRequestPointerLock(); + } +} + +function exitPointerLock() { + if (document.exitPointerLock) { + document.exitPointerLock(); + } else if (document.mozExitPointerLock) { + document.mozExitPointerLock(); + } +} + +function pointerLockElement() { + return (document.pointerLockElement || + document.mozPointerLockElement || + null); +} + +function addPointerlockchangeEventListener(listener) { + if ("onpointerlockchange" in document) { + document.addEventListener("pointerlockchange", listener); + } else if ("onmozpointerlockchange" in document) { + document.addEventListener("mozpointerlockchange", listener); + } +} + function copyTouch(touch, timeStamp) { return { identifier: touch.identifier, @@ -325,6 +356,36 @@ function handleKeydown(evt) { } } +function updateMouseButtons(buttons) { + for (var button = 0; button < 3; button += 1) { + var flag = 1 << button; + if ((buttons&flag) != (mouseButtons&flag)) { + ws.send("b" + button + ";" + (buttons&flag ? 1 : 0)); + } + } + mouseButtons = buttons; +} + +function handleMousedown(evt) { + updateMouseButtons(evt.buttons); +} + +function handleMouseup(evt) { + updateMouseButtons(evt.buttons); +} + +function handleMousemove(evt) { + updateMove(evt.movementX, evt.movementY); +} + +function handleWheel(evt) { + if (evt.deltaMode == WheelEvent.DOM_DELTA_PIXEL) { + updateScroll(evt.deltaX, evt.deltaY, true); + } else if (evt.deltaMode == WheelEvent.DOM_DELTA_LINE) { + updateScroll(evt.deltaX*20, evt.deltaY*20, true); + } +} + function challengeResponse(message) { var shaObj = new jsSHA("SHA-256", "TEXT"); shaObj.setHMACKey(message, "TEXT"); @@ -347,6 +408,7 @@ window.addEventListener("load", function() { var keyboard = document.getElementById("keyboard"); var fullscreenbutton = document.getElementById("fullscreenbutton"); var keyboardtext = document.getElementById("keyboardtext"); + var mouse = document.getElementById("mouse") var activeScene; var keysActiveName; @@ -355,6 +417,9 @@ window.addEventListener("load", function() { if (fullscreenElement() && !scene.classList.contains("fullscreen")) { exitFullscreen(); } + if (pointerLockElement() && activeScene != mouse) { + exitPointerLock(); + } keyboardtext.value = ""; scenes.forEach(function(otherScene) { otherScene.classList.toggle("hidden", otherScene != scene); @@ -480,7 +545,9 @@ window.addEventListener("load", function() { }); window.onpopstate = function() { if (authenticated) { - if ((history.state || "").split(":")[0] == "keys") { + if (pointerLockElement()) { + showScene(mouse); + } else if ((history.state || "").split(":")[0] == "keys") { showKeys(history.state.substr("keys:".length)); } else if (history.state == "keyboard") { showKeyboard(); @@ -506,4 +573,24 @@ window.addEventListener("load", function() { handleKeydown(evt); } }); + addPointerlockchangeEventListener(function() { + if (pointerLockElement() && !authenticated) { + exitPointerLock(); + } + window.onpopstate(); + }); + document.addEventListener("mousedown", function(event) { + if (activeScene != mouse && event.buttons == 1 && event.target.classList.contains("touch")) { + requestPointerLock(mouse); + } + }); + ["touchstart", "touchend", "touchcancel", "touchmove"].forEach(function(type) { + mouse.addEventListener(type, function(evt) { + evt.preventDefault(); + }); + }); + mouse.addEventListener("mousedown", handleMousedown); + mouse.addEventListener("mouseup", handleMouseup); + mouse.addEventListener("mousemove", handleMousemove); + mouse.addEventListener("wheel", handleWheel); }); diff --git a/webdata/index.html b/webdata/index.html index 80b3493..1ffd6cc 100644 --- a/webdata/index.html +++ b/webdata/index.html @@ -68,3 +68,6 @@ + diff --git a/webdata/main.css b/webdata/main.css index 8f8df9c..a7d917e 100644 --- a/webdata/main.css +++ b/webdata/main.css @@ -76,7 +76,8 @@ button:focus { max-width: 100%; } -#pad > p { +#pad > p, +#mouse > p { color: gray; text-shadow: -1px -1px 0 black, @@ -89,7 +90,8 @@ button:focus { } @media (max-width: 32rem) { - #pad > p { + #pad > p, + #mouse > p { font-size: 13vw; } }