From e2a6c1eee5d05878f49098f0f4cb1aca99251dcb Mon Sep 17 00:00:00 2001 From: ksen0 Date: Mon, 11 Aug 2025 22:59:45 +0200 Subject: [PATCH 1/6] mouse offscreen behaviors bugfix --- src/accessibility/outputs.js | 16 +++++++--------- src/events/mouse.js | 6 ++---- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/accessibility/outputs.js b/src/accessibility/outputs.js index d712c008bc..bf203ddfd9 100644 --- a/src/accessibility/outputs.js +++ b/src/accessibility/outputs.js @@ -579,19 +579,17 @@ p5.prototype._getPos = function (x, y) { function _canvasLocator(args, canvasWidth, canvasHeight) { const noRows = 10; const noCols = 10; + let x = args[0]; let y = args[1]; - if (x < 0 || x >= canvasWidth || y < 0 || y >= canvasHeight) { - return null; - } + let locX = Math.floor(x / canvasWidth * noRows); let locY = Math.floor(y / canvasHeight * noCols); - if (locX === noRows) { - locX = locX - 1; - } - if (locY === noCols) { - locY = locY - 1; - } + + // clamp out of bounds values + locX = Math.min(Math.max(locX, 0), noRows - 1); + locY = Math.min(Math.max(locY, 0), noCols - 1); + return { locX, locY diff --git a/src/events/mouse.js b/src/events/mouse.js index c9a53cbe96..40363a94a6 100644 --- a/src/events/mouse.js +++ b/src/events/mouse.js @@ -810,15 +810,13 @@ p5.prototype._updateNextMouseCoords = function(e) { e ); + this._setProperty('movedX', e.movementX); + this._setProperty('movedY', e.movementY); this._setProperty('mouseX', mousePos.x); this._setProperty('mouseY', mousePos.y); this._setProperty('winMouseX', mousePos.winX); this._setProperty('winMouseY', mousePos.winY); - const deltaX = this.mouseX - this.pmouseX; - const deltaY = this.mouseY - this.pmouseY; - this._setProperty('movedX', deltaX); - this._setProperty('movedY', deltaY); } if (!this._hasMouseInteracted) { From c0b5418a940333d8633e28980e8ea273a2affaf2 Mon Sep 17 00:00:00 2001 From: ksen0 Date: Thu, 21 Aug 2025 08:28:11 +0200 Subject: [PATCH 2/6] Calculate mouse movement delta depending on pointer lock --- src/events/mouse.js | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/events/mouse.js b/src/events/mouse.js index 40363a94a6..a4c604aaa3 100644 --- a/src/events/mouse.js +++ b/src/events/mouse.js @@ -19,6 +19,11 @@ import * as constants from '../core/constants'; * * Note: `movedX` continues updating even when * requestPointerLock() is active. + * But keep in mind that during an active pointer lock, mouseX and pmouseX + * are not locked, so `movedX` is based on + * the MouseEvent's movementX + * value. This value may behave different in different browsers when the user + * is zoomed in or out. * * @property {Number} movedX * @readOnly @@ -810,13 +815,31 @@ p5.prototype._updateNextMouseCoords = function(e) { e ); - this._setProperty('movedX', e.movementX); - this._setProperty('movedY', e.movementY); + this._setProperty('mouseX', mousePos.x); this._setProperty('mouseY', mousePos.y); this._setProperty('winMouseX', mousePos.winX); this._setProperty('winMouseY', mousePos.winY); + if (document.pointerLockElement === null) { + // https://developer.mozilla.org/en-US/docs/Web/API/Document/pointerLockElement + // "The pointerLockElement ... is null if lock is pending, pointer is unlocked, + // or the target is in another document." + // In this case, we use mouseX/Y and pmousX/Y to calculate the distance, + // which allows movedX/Y to look consistent at different zoom levels acorss + // browsers. + const deltaX = this.mouseX - this.pmouseX; + const deltaY = this.mouseY - this.pmouseY; + this._setProperty('movedX', deltaX); + this._setProperty('movedY', deltaY); + } + else { + // Because mouseX/Y and pmouseX/Y are locked, the elements movementX/Y + // is used for movedX/Y - this maz behave differently on different + // browsers at different zoom levels. + this._setProperty('movedX', e.movementX); + this._setProperty('movedY', e.movementY); + } } if (!this._hasMouseInteracted) { From 36668ba7158ad8a196b6f3da1d0fea15cab0ce25 Mon Sep 17 00:00:00 2001 From: ksen0 Date: Thu, 21 Aug 2025 17:59:13 +0200 Subject: [PATCH 3/6] Added manual test for movedX/Y and requestPointerLock --- src/events/mouse.js | 8 ++--- .../pointer-lock-movedx/index.html | 16 ++++++++++ .../pointer-lock-movedx/sketch.js | 31 +++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 test/manual-test-examples/mouse-events/pointer-lock-movedx/index.html create mode 100644 test/manual-test-examples/mouse-events/pointer-lock-movedx/sketch.js diff --git a/src/events/mouse.js b/src/events/mouse.js index a4c604aaa3..a4937066b3 100644 --- a/src/events/mouse.js +++ b/src/events/mouse.js @@ -21,9 +21,9 @@ import * as constants from '../core/constants'; * requestPointerLock() is active. * But keep in mind that during an active pointer lock, mouseX and pmouseX * are not locked, so `movedX` is based on - * the MouseEvent's movementX - * value. This value may behave different in different browsers when the user - * is zoomed in or out. + * the MouseEvent's movementX value + * (which may behave differently in different browsers when the user + * is zoomed in or out). * * @property {Number} movedX * @readOnly @@ -835,7 +835,7 @@ p5.prototype._updateNextMouseCoords = function(e) { } else { // Because mouseX/Y and pmouseX/Y are locked, the elements movementX/Y - // is used for movedX/Y - this maz behave differently on different + // is used for movedX/Y - this may behave differently on different // browsers at different zoom levels. this._setProperty('movedX', e.movementX); this._setProperty('movedY', e.movementY); diff --git a/test/manual-test-examples/mouse-events/pointer-lock-movedx/index.html b/test/manual-test-examples/mouse-events/pointer-lock-movedx/index.html new file mode 100644 index 0000000000..202329a285 --- /dev/null +++ b/test/manual-test-examples/mouse-events/pointer-lock-movedx/index.html @@ -0,0 +1,16 @@ + + + + + + + +

Manual test for movedX/Y with/without zoom and with/without pointer lock

+
    +
  • If you move the mouse around, you should see 1 moving circle and 1 still. While dragging mouse, they should move at the same rate.
  • +
  • After zooming in/out, on all browsers, the circles should still move visually a constant distance relative to each other.
  • +
  • Press any key to request pointer lock. Background will be pink if and only if pointer is locked. Now, if you drag the mouse, the small circle should be static (because mouseX/Y are locked) and the big circle should move unsurprisingly.
  • +
+ + + diff --git a/test/manual-test-examples/mouse-events/pointer-lock-movedx/sketch.js b/test/manual-test-examples/mouse-events/pointer-lock-movedx/sketch.js new file mode 100644 index 0000000000..05a02a1b00 --- /dev/null +++ b/test/manual-test-examples/mouse-events/pointer-lock-movedx/sketch.js @@ -0,0 +1,31 @@ +function setup() { + createCanvas(400, 400); +} + +let x = 200; +let y = 200; +function draw() { + if (document.pointerLockElement === null){ + background(220); + } else{ + background(200,0,200); + } + + text(movedX, 20, 20); + text(movedY, 20, 40); + text(mouseX, 50, 20); + text(mouseY, 50, 40); + circle(mouseX, mouseY, 30); + + //https://editor.p5js.org/SableRaf/sketches/zAXl3tNm5 + if(mouseIsPressed){ + x += movedX; + y += movedY; + } + + circle(x, y, 50); + +} +function keyPressed() { + requestPointerLock(); +} \ No newline at end of file From f6a6bca6bd8dc874da999c5463179e968c6a16f9 Mon Sep 17 00:00:00 2001 From: kit <1304340+ksen0@users.noreply.github.com> Date: Thu, 21 Aug 2025 21:05:43 +0200 Subject: [PATCH 4/6] Update src/events/mouse.js Co-authored-by: Perminder Singh <127239756+perminder-17@users.noreply.github.com> --- src/events/mouse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/events/mouse.js b/src/events/mouse.js index a4937066b3..7dc7d6081d 100644 --- a/src/events/mouse.js +++ b/src/events/mouse.js @@ -825,7 +825,7 @@ p5.prototype._updateNextMouseCoords = function(e) { // https://developer.mozilla.org/en-US/docs/Web/API/Document/pointerLockElement // "The pointerLockElement ... is null if lock is pending, pointer is unlocked, // or the target is in another document." - // In this case, we use mouseX/Y and pmousX/Y to calculate the distance, + // In this case, we use mouseX/Y and pmouseX/Y to calculate the distance, // which allows movedX/Y to look consistent at different zoom levels acorss // browsers. const deltaX = this.mouseX - this.pmouseX; From 4c24f730a9e0e0661c208d410505bb0b2888b7b7 Mon Sep 17 00:00:00 2001 From: kit <1304340+ksen0@users.noreply.github.com> Date: Thu, 21 Aug 2025 21:05:48 +0200 Subject: [PATCH 5/6] Update src/events/mouse.js Co-authored-by: Perminder Singh <127239756+perminder-17@users.noreply.github.com> --- src/events/mouse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/events/mouse.js b/src/events/mouse.js index 7dc7d6081d..52d2fc7f28 100644 --- a/src/events/mouse.js +++ b/src/events/mouse.js @@ -826,7 +826,7 @@ p5.prototype._updateNextMouseCoords = function(e) { // "The pointerLockElement ... is null if lock is pending, pointer is unlocked, // or the target is in another document." // In this case, we use mouseX/Y and pmouseX/Y to calculate the distance, - // which allows movedX/Y to look consistent at different zoom levels acorss + // which allows movedX/Y to look consistent at different zoom levels across // browsers. const deltaX = this.mouseX - this.pmouseX; const deltaY = this.mouseY - this.pmouseY; From 852162bb90b53d2e55f285bf3c6fe10dea4f05c9 Mon Sep 17 00:00:00 2001 From: ksen0 Date: Thu, 21 Aug 2025 22:36:42 +0200 Subject: [PATCH 6/6] Update movedX/Y documentation --- src/events/mouse.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/events/mouse.js b/src/events/mouse.js index 52d2fc7f28..7d83626962 100644 --- a/src/events/mouse.js +++ b/src/events/mouse.js @@ -20,7 +20,7 @@ import * as constants from '../core/constants'; * Note: `movedX` continues updating even when * requestPointerLock() is active. * But keep in mind that during an active pointer lock, mouseX and pmouseX - * are not locked, so `movedX` is based on + * are locked, so `movedX` is based on * the MouseEvent's movementX value * (which may behave differently in different browsers when the user * is zoomed in or out). @@ -69,6 +69,11 @@ p5.prototype.movedX = 0; * * Note: `movedY` continues updating even when * requestPointerLock() is active. + * But keep in mind that during an active pointer lock, mouseX and pmouseX + * are locked, so `movedX` is based on + * the MouseEvent's movementX value + * (which may behave differently in different browsers when the user + * is zoomed in or out). * * @property {Number} movedY * @readOnly