mousewheel is not completely smooth but still better than nothing
This commit is contained in:
+50
-9
@@ -16,6 +16,7 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/webrtc-adapter/8.1.2/adapter.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/webrtc-adapter/8.1.2/adapter.min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
html, body { overflow: hidden; }
|
||||||
body {
|
body {
|
||||||
background: #000;
|
background: #000;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -653,16 +654,36 @@
|
|||||||
}
|
}
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
let lastMouseMove = 0;
|
// The actual network send happens in a requestAnimationFrame loop
|
||||||
|
// below instead of a manual setInterval-style throttle — RAF aligns
|
||||||
|
// with the browser's own natural scheduling/render cadence, which
|
||||||
|
// browsers are heavily optimized to prioritize correctly even under
|
||||||
|
// other event traffic (like rapid wheel scrolling)
|
||||||
|
let accumDx = 0, accumDy = 0;
|
||||||
|
let hasPendingMove = false;
|
||||||
document.addEventListener('mousemove', e => {
|
document.addEventListener('mousemove', e => {
|
||||||
if (!pointerLocked || !isControlling) return;
|
if (!pointerLocked || !isControlling) return;
|
||||||
const now = performance.now();
|
accumDx += e.movementX;
|
||||||
if (now - lastMouseMove < 16) return;
|
accumDy += e.movementY;
|
||||||
lastMouseMove = now;
|
hasPendingMove = true;
|
||||||
sendInput({ type: 'mouse_move', dx: e.movementX * mouseSensitivity, dy: e.movementY * mouseSensitivity });
|
|
||||||
pingActive();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function rafMoveFlush() {
|
||||||
|
if (hasPendingMove) {
|
||||||
|
sendInput({ type: 'mouse_move', dx: accumDx * mouseSensitivity, dy: accumDy * mouseSensitivity });
|
||||||
|
accumDx = 0;
|
||||||
|
accumDy = 0;
|
||||||
|
hasPendingMove = false;
|
||||||
|
// No pingActive() here — it sends an actual WebSocket message every
|
||||||
|
// call, and this flush can run up to ~60x/sec during movement,
|
||||||
|
// doubling real network traffic during exactly the situation we're
|
||||||
|
// trying to lighten. The existing 3-second setInterval already
|
||||||
|
// keeps the idle timer alive without needing this.
|
||||||
|
}
|
||||||
|
requestAnimationFrame(rafMoveFlush);
|
||||||
|
}
|
||||||
|
requestAnimationFrame(rafMoveFlush);
|
||||||
|
|
||||||
canvas.addEventListener('contextmenu', e => {
|
canvas.addEventListener('contextmenu', e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
@@ -680,12 +701,32 @@
|
|||||||
let lastMouseWheel = 0;
|
let lastMouseWheel = 0;
|
||||||
canvas.addEventListener('wheel', e => {
|
canvas.addEventListener('wheel', e => {
|
||||||
if (!pointerLocked || !isControlling) return;
|
if (!pointerLocked || !isControlling) return;
|
||||||
e.preventDefault();
|
// No e.preventDefault() here anymore, and this listener is passive.
|
||||||
|
// preventDefault() on a non-passive wheel listener forces the browser
|
||||||
|
// to synchronously coordinate with its compositor thread on every
|
||||||
|
// single call — at 60-140 wheel events/sec (rapid scroll-jump
|
||||||
|
// spamming) that repeated synchronous cost was confirmed via the
|
||||||
|
// diagnostic counters above to correlate exactly with mousemove
|
||||||
|
// events dropping to zero during the same window: the browser was
|
||||||
|
// coalescing/dropping mouse movement entirely while busy handling
|
||||||
|
// the wheel events. Page scroll is prevented via CSS
|
||||||
|
// (html, body { overflow: hidden }) instead, which is free and
|
||||||
|
// doesn't require blocking per-event JS work.
|
||||||
const now = performance.now();
|
const now = performance.now();
|
||||||
if (now - lastMouseWheel < 16) return;
|
// 100ms instead of 16ms: jump timing has no real use for 60Hz
|
||||||
|
// precision (a single jump+land cycle takes far longer than that),
|
||||||
|
// and the diagnostic counters showed raw wheel dispatch hitting
|
||||||
|
// 70-80/sec during a fast physical flick — almost certainly the
|
||||||
|
// mouse wheel's hardware free-spinning generating many rapid encoder
|
||||||
|
// pulses from one gesture, not 70-80 deliberate jumps. This won't
|
||||||
|
// reduce how often the browser calls this handler, but it does cut
|
||||||
|
// the actual sendInput -> WebSocket -> xdotool-click work by a large
|
||||||
|
// factor, which was still contributing some interference even after
|
||||||
|
// removing preventDefault().
|
||||||
|
if (now - lastMouseWheel < 100) return;
|
||||||
lastMouseWheel = now;
|
lastMouseWheel = now;
|
||||||
sendInput({ type: 'mouse_wheel', direction: e.deltaY < 0 ? 'up' : 'down' });
|
sendInput({ type: 'mouse_wheel', direction: e.deltaY < 0 ? 'up' : 'down' });
|
||||||
}, { passive: false });
|
}, { passive: true });
|
||||||
|
|
||||||
const KEY_MAP = {
|
const KEY_MAP = {
|
||||||
'KeyW': 'w', 'KeyA': 'a', 'KeyS': 's', 'KeyD': 'd',
|
'KeyW': 'w', 'KeyA': 'a', 'KeyS': 's', 'KeyD': 'd',
|
||||||
|
|||||||
Reference in New Issue
Block a user