www.spaceplanner.app

Web client to the spaceplanner API
git clone git://jacobedwards.org/www.spaceplanner.app
Log | Files | Refs

commit 4e47d467244ae03cd3241f296d1dec31f1e4ef5d
parent 0375b309d1d308ab6dabc119e04232cdedc1931a
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date:   Thu, 17 Oct 2024 11:42:21 -0700

Prevent multiple inputs on most pointer handlers

This is more inline with the desired behavior anyway, but it's
extremely important for the next change.

It's implemented by creating a single handler function which will
stop propagation of an event if multiple inputs are detected, so
if you have some handlers that accept multiple inputs you can just
place this handler after it.

One caveat of the implementation at the moment is that it doesn't
handle mouse inputs as you would expect (due to the design of pointer
events).  This could be fixed in the future without much trouble
if it's a big issue, if it's even the desired behavior.

Diffstat:
Mfiles/floorplans/floorplan/main.js | 39+++++++++++++++++++++++++++++----------
1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/files/floorplans/floorplan/main.js b/files/floorplans/floorplan/main.js @@ -34,9 +34,10 @@ const modes = { points: true, handlers: { contextmenu: preventDefaultHandler, - pointerdown: [selectionHandler, precisePointHandler, precisePointMapHandler, furnitureHandler], - pointermove: [precisePointHandler, furnitureHandler], - pointerup: [precisePointHandler, precisePointMapHandler, furnitureHandler], + pointerdown: [singlePointerHandler, selectionHandler, precisePointHandler, precisePointMapHandler, furnitureHandler], + pointermove: [singlePointerHandler, precisePointHandler, furnitureHandler], + pointerup: [singlePointerHandler, precisePointHandler, precisePointMapHandler, furnitureHandler], + pointercancel: [singlePointerHandler, selectionHandler, precisePointHandler, precisePointMapHandler, furnitureHandler], keydown: [keyHandler], dblclick: [precisePointMapHandler, furnitureHandler], select: selectHandler, @@ -68,6 +69,7 @@ const debug = (new URLSearchParams(new URL(document.URL).search)).get("debug") ! // turn off bubbling const escapeEvent = new Event("escape") +const cancelEvent = new PointerEvent("pointercancel") etc.handle_wrap(init) @@ -248,14 +250,7 @@ function run(editor) { editor.fitToView() }) - let preventWhenSel = function(e) { - if (editor.draw.findOne(".selected")) { - e.preventDefault() - } - } - editor.draw.on("touchmove", function(e){ e.preventDefault() }); - editor.draw.on("pinchZoomStart", preventWhenSel) editor.draw.on("pinchZoomStart", function() { State.panZoom |= zoomBit }) editor.draw.on("pinchZoomEnd", function() { State.panZoom &= ~zoomBit}) editor.draw.on("panStart", function() { State.panZoom |= panBit }) @@ -1553,6 +1548,30 @@ function preventDefaultHandler(event) { handled(event) } +function singlePointerHandler(ev, editor, state) { + if (ev.type === "pointerdown") { + state[ev.pointerId] = true + console.warn("singlePointerHandler", ev.pointerId, true) + } else if (ev.type === "pointerup" || ev.type === "pointercancel") { + delete state[ev.pointerId] + console.warn("singlePointerHandler", ev.pointerId, false) + } + + // Send all events but pointerdown on to the other handlers + if (ev.type !== "pointerdown" && ev.type !== "pointermove") { + return + } + + let cnt = 0 + for (let k in state) { + if (++cnt > 1) { + editor.draw.fire(cancelEvent); + handled(ev) + return + } + } +} + function notify(message, id) { console.log("Notify", message)