From 6ea972bcf8723952e73b09f962cc42ae895cdc82 Mon Sep 17 00:00:00 2001 From: Norbert Renner Date: Fri, 30 Apr 2021 18:30:01 +0200 Subject: [PATCH] Avoid accidental zooms while drawing beeline --- js/plugin/Routing.js | 10 ++++++ js/util/ClickTolerantBoxZoom.js | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 js/util/ClickTolerantBoxZoom.js diff --git a/js/plugin/Routing.js b/js/plugin/Routing.js index 9e56d47..0bcb459 100644 --- a/js/plugin/Routing.js +++ b/js/plugin/Routing.js @@ -180,6 +180,16 @@ BR.Routing = L.Routing.extend({ this._draw ); + // avoid accidental shift-drag zooms while drawing beeline with shift-click + this._map.boxZoom.disable(); + this._map.addHandler('boxZoom', BR.ClickTolerantBoxZoom); + this._draw.on('enabled', function () { + this._map.boxZoom.tolerant = true; + }); + this._draw.on('disabled', function () { + this._map.boxZoom.tolerant = false; + }); + // remove listeners registered in super.onAdd, keys not working when map container lost focus // (by navbar/sidebar interaction), use document instead L.DomEvent.removeListener(this._container, 'keydown', this._keydownListener, this); diff --git a/js/util/ClickTolerantBoxZoom.js b/js/util/ClickTolerantBoxZoom.js new file mode 100644 index 0000000..dc5ee17 --- /dev/null +++ b/js/util/ClickTolerantBoxZoom.js @@ -0,0 +1,55 @@ +/** + * Avoids conflict between shift-click and shift-drag. + * Extends BoxZoom to support a small click tolerance like in Draggable and + * a larger drag tolerance as a "neutral zone" before starting with box zoom dragging, + * to avoid accidental zooms. + */ +BR.ClickTolerantBoxZoom = L.Map.BoxZoom.extend({ + clickTolerance: L.Draggable.prototype.options.clickTolerance, + // use more than clickTolerance before starting box zoom to surely avoid accidental zooms + dragTolerance: 15, + // flag to enable or disable click/drag tolerance, classic BoxZoom behaviour when false + tolerant: true, + + // "neutral zone", state between clickTolerance and dragTolerance, + // already signals dragging to map and thus prevents click + _preMoved: false, + + moved: function () { + return this._preMoved || this._moved; + }, + + _resetState: function () { + L.Map.BoxZoom.prototype._resetState.call(this); + this._preMoved = false; + }, + + _onMouseMove: function (e) { + if (!this._moved) { + const point = this._map.mouseEventToContainerPoint(e); + + // derived from L.Draggable._onMove + var offsetPoint = point.clone()._subtract(this._startPoint); + var offset = Math.abs(offsetPoint.x || 0) + Math.abs(offsetPoint.y || 0); + + if (this.tolerant && offset < this.dragTolerance) { + if (!this._preMoved && offset >= this.clickTolerance) { + this._preMoved = true; + } + + return; + } + } + + L.Map.BoxZoom.prototype._onMouseMove.call(this, e); + }, + + _onMouseUp: function (e) { + L.Map.BoxZoom.prototype._onMouseUp.call(this, e); + + if (!this._moved && this._preMoved) { + this._clearDeferredResetState(); + this._resetStateTimeout = setTimeout(L.Util.bind(this._resetState, this), 0); + } + }, +});