From 8e9a34b2604b28f4a9aa4b724e6f5455b20d2a4e Mon Sep 17 00:00:00 2001 From: Juha Lindstedt Date: Tue, 28 May 2019 21:48:20 +0300 Subject: [PATCH] Add touch support for NavigationControl's compass button + add pitch indication to icon (#8226) --- src/ui/control/navigation_control.js | 6 +++- src/ui/handler/drag_rotate.js | 42 +++++++++++++++++++++------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/ui/control/navigation_control.js b/src/ui/control/navigation_control.js index a2fe2afc781..64c849b02fc 100644 --- a/src/ui/control/navigation_control.js +++ b/src/ui/control/navigation_control.js @@ -68,7 +68,7 @@ class NavigationControl { } _rotateCompassArrow() { - const rotate = `rotate(${this._map.transform.angle * (180 / Math.PI)}deg)`; + const rotate = `rotateX(${this._map.transform.pitch}deg) rotateZ(${this._map.transform.angle * (180 / Math.PI)}deg)`; this._compassArrow.style.transform = rotate; } @@ -80,9 +80,11 @@ class NavigationControl { } if (this.options.showCompass) { this._map.on('rotate', this._rotateCompassArrow); + this._map.on('pitch', this._rotateCompassArrow); this._rotateCompassArrow(); this._handler = new DragRotateHandler(map, {button: 'left', element: this._compass}); DOM.addEventListener(this._compass, 'mousedown', this._handler.onMouseDown); + DOM.addEventListener(this._compass, 'touchstart', this._handler.onMouseDown); this._handler.enable(); } return this._container; @@ -95,7 +97,9 @@ class NavigationControl { } if (this.options.showCompass) { this._map.off('rotate', this._rotateCompassArrow); + this._map.off('pitch', this._rotateCompassArrow); DOM.removeEventListener(this._compass, 'mousedown', this._handler.onMouseDown); + DOM.removeEventListener(this._compass, 'touchstart', this._handler.onMouseDown); this._handler.disable(); delete this._handler; } diff --git a/src/ui/handler/drag_rotate.js b/src/ui/handler/drag_rotate.js index a43b96e1736..5c63f73a812 100644 --- a/src/ui/handler/drag_rotate.js +++ b/src/ui/handler/drag_rotate.js @@ -128,12 +128,16 @@ class DragRotateHandler { onMouseDown(e: MouseEvent) { if (this._state !== 'enabled') return; - if (this._button === 'right') { - this._eventButton = DOM.mouseButton(e); - if (this._eventButton !== (e.ctrlKey ? 0 : 2)) return; - } else { - if (e.ctrlKey || DOM.mouseButton(e) !== 0) return; - this._eventButton = 0; + const touchEvent = e.type === 'touchstart'; + + if (!touchEvent) { + if (this._button === 'right') { + this._eventButton = DOM.mouseButton(e); + if (this._eventButton !== (e.ctrlKey ? 0 : 2)) return; + } else { + if (e.ctrlKey || DOM.mouseButton(e) !== 0) return; + this._eventButton = 0; + } } DOM.disableDrag(); @@ -143,8 +147,11 @@ class DragRotateHandler { // window-level event listeners give us the best shot at capturing events that // fall outside the map canvas element. Use `{capture: true}` for the move event // to prevent map move events from being fired during a drag. - window.document.addEventListener('mousemove', this._onMouseMove, {capture: true}); - window.document.addEventListener('mouseup', this._onMouseUp); + const moveEvent = touchEvent ? 'touchmove' : 'mousemove'; + const upEvent = touchEvent ? 'touchend' : 'mouseup'; + + window.document.addEventListener(moveEvent, this._onMouseMove, { capture: true }); + window.document.addEventListener(upEvent, this._onMouseUp); // Deactivate when the window loses focus. Otherwise if a mouseup occurs when the window // isn't in focus, dragging will continue even though the mouse is no longer pressed. @@ -152,14 +159,20 @@ class DragRotateHandler { this._state = 'pending'; this._inertia = [[browser.now(), this._map.getBearing()]]; - this._startPos = this._lastPos = DOM.mousePos(this._el, e); + this._startPos = this._lastPos = touchEvent ? + DOM.touchPos(this._el, e)[0] : + DOM.mousePos(this._el, e); this._center = this._map.transform.centerPoint; // Center of rotation e.preventDefault(); } _onMouseMove(e: MouseEvent) { - const pos = DOM.mousePos(this._el, e); + const touchEvent = e.type === 'touchmove'; + const pos = touchEvent ? + DOM.touchPos(this._el, e)[0] : + DOM.mousePos(this._el, e); + if (this._lastPos.equals(pos)) { return; } @@ -214,6 +227,13 @@ class DragRotateHandler { } _onMouseUp(e: MouseEvent) { + const touchEvent = e.type === 'touchend'; + + if (touchEvent) { + if (this._lastPos === this._startPos) { + this._el.click(); + } + } if (DOM.mouseButton(e) !== this._eventButton) return; switch (this._state) { case 'active': @@ -258,6 +278,8 @@ class DragRotateHandler { _unbind() { window.document.removeEventListener('mousemove', this._onMouseMove, {capture: true}); window.document.removeEventListener('mouseup', this._onMouseUp); + window.document.removeEventListener('touchmove', this._onMouseMove, { capture: true }); + window.document.removeEventListener('touchend', this._onMouseUp); window.removeEventListener('blur', this._onBlur); DOM.enableDrag(); }