diff --git a/src/ui/handler/drag_pan.js b/src/ui/handler/drag_pan.js index 069cce450bc..70855c679a3 100644 --- a/src/ui/handler/drag_pan.js +++ b/src/ui/handler/drag_pan.js @@ -114,18 +114,9 @@ class DragPanHandler { this._lastMoveEvent = e; e.preventDefault(); - const pos = DOM.mousePos(this._el, e); + this._pos = DOM.mousePos(this._el, e); this._drainInertiaBuffer(); - this._inertia.push([browser.now(), pos]); - - // if the dragging animation was interrupted (e.g. by another handler), - // we need to reestablish a _previousPos before we can resume dragging - if (!this._previousPos) { - this._previousPos = pos; - return; - } - - this._pos = pos; + this._inertia.push([browser.now(), this._pos]); if (!this.isActive()) { // we treat the first move event (rather than the mousedown event) @@ -134,12 +125,9 @@ class DragPanHandler { this._map.moving = true; this._fireEvent('dragstart', e); this._fireEvent('movestart', e); - - this._map._startAnimation(this._onDragFrame, this._onDragFinished); } - // ensure a new render frame is scheduled - this._map._update(); + this._map._startAnimation(this._onDragFrame); } /** diff --git a/src/ui/handler/drag_rotate.js b/src/ui/handler/drag_rotate.js index 7251cd31760..87a5c9f08e9 100644 --- a/src/ui/handler/drag_rotate.js +++ b/src/ui/handler/drag_rotate.js @@ -55,8 +55,7 @@ class DragRotateHandler { '_onDown', '_onMove', '_onUp', - '_onDragFrame', - '_onDragFinished' + '_onDragFrame' ], this); } @@ -139,15 +138,7 @@ class DragRotateHandler { _onMove(e: MouseEvent) { this._lastMoveEvent = e; - const pos = DOM.mousePos(this._el, e); - // if the dragging animation was interrupted (e.g. by another handler), - // we need to reestablish a _previousPos before we can resume dragging - if (!this._previousPos) { - this._previousPos = pos; - return; - } - - this._pos = pos; + this._pos = DOM.mousePos(this._el, e); if (!this.isActive()) { this._active = true; @@ -157,22 +148,9 @@ class DragRotateHandler { if (this._pitchWithRotate) { this._fireEvent('pitchstart', e); } - - this._map._startAnimation(this._onDragFrame, this._onDragFinished); } - // ensure a new render frame is scheduled - this._map._update(); - } - - _onUp(e: MouseEvent | FocusEvent) { - window.document.removeEventListener('mousemove', this._onMove, {capture: true}); - window.document.removeEventListener('mouseup', this._onUp); - window.removeEventListener('blur', this._onUp); - - DOM.enableDrag(); - - this._onDragFinished(e); + this._map._startAnimation(this._onDragFrame); } _onDragFrame(tr: Transform) { @@ -204,7 +182,13 @@ class DragRotateHandler { this._previousPos = this._pos; } - _onDragFinished(e: MouseEvent | FocusEvent | void) { + _onUp(e: MouseEvent | FocusEvent) { + window.document.removeEventListener('mousemove', this._onMove, {capture: true}); + window.document.removeEventListener('mouseup', this._onUp); + window.removeEventListener('blur', this._onUp); + + DOM.enableDrag(); + if (!this.isActive()) return; this._active = false; diff --git a/test/unit/ui/handler/drag_pan.test.js b/test/unit/ui/handler/drag_pan.test.js index 7c63f17321e..66ce2af308e 100644 --- a/test/unit/ui/handler/drag_pan.test.js +++ b/test/unit/ui/handler/drag_pan.test.js @@ -131,21 +131,47 @@ test('DragPanHandler requests a new render frame after each mousemove event', (t t.end(); }); -test('DragPanHandler recovers after interruption by another handler', (t) => { +test('DragPanHandler can interleave with another handler', (t) => { // https://github.com/mapbox/mapbox-gl-js/issues/6106 const map = createMap(); - const initialCenter = map.getCenter(); - simulate.mousedown(map.getCanvas(), {clientX: 10, clientY: 10}); - simulate.mousemove(map.getCanvas(), {clientX: 12, clientY: 10}); + + const dragstart = t.spy(); + const drag = t.spy(); + const dragend = t.spy(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvas()); + map._updateCamera(); + t.equal(dragstart.callCount, 0); + t.equal(drag.callCount, 0); + t.equal(dragend.callCount, 0); + + simulate.mousemove(map.getCanvas()); map._updateCamera(); + t.equal(dragstart.callCount, 1); + t.equal(drag.callCount, 1); + t.equal(dragend.callCount, 0); - // simluates another handler taking over + // simulates another handler taking over map.stop(); + t.equal(dragstart.callCount, 1); + t.equal(drag.callCount, 1); + t.equal(dragend.callCount, 0); - simulate.mousemove(map.getCanvas(), {clientX: 14, clientY: 10}); - simulate.mousemove(map.getCanvas(), {clientX: 16, clientY: 10}); + simulate.mousemove(map.getCanvas()); map._updateCamera(); - t.equalWithPrecision(map.getCenter().lng, initialCenter.lng - 2.8125, 1e-4); + t.equal(dragstart.callCount, 1); + t.equal(drag.callCount, 2); + t.equal(dragend.callCount, 0); + + simulate.mouseup(map.getCanvas()); + map._updateCamera(); + t.equal(dragstart.callCount, 1); + t.equal(drag.callCount, 2); + t.equal(dragend.callCount, 1); map.remove(); t.end(); diff --git a/test/unit/ui/handler/drag_rotate.test.js b/test/unit/ui/handler/drag_rotate.test.js index 619eb8f9631..c7bc1ade73a 100644 --- a/test/unit/ui/handler/drag_rotate.test.js +++ b/test/unit/ui/handler/drag_rotate.test.js @@ -390,20 +390,47 @@ test('DragRotateHandler requests a new render frame after each mousemove event', t.end(); }); -test('DragRotateHandler recovers after interruption by another handler', (t) => { +test('DragRotateHandler can interleave with another handler', (t) => { // https://github.com/mapbox/mapbox-gl-js/issues/6106 const map = createMap(); - const initialBearing = map.getBearing(); - simulate.mousedown(map.getCanvas(), {buttons: 2, button: 2, clientX: 10, clientY: 10}); - simulate.mousemove(map.getCanvas(), {buttons: 2, clientX: 12, clientY: 10}); + + const rotatestart = t.spy(); + const rotate = t.spy(); + const rotateend = t.spy(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvas(), {buttons: 2, button: 2}); map._updateCamera(); + t.equal(rotatestart.callCount, 0); + t.equal(rotate.callCount, 0); + t.equal(rotateend.callCount, 0); - // simluates another handler taking over + simulate.mousemove(map.getCanvas(), {buttons: 2}); + map._updateCamera(); + t.equal(rotatestart.callCount, 1); + t.equal(rotate.callCount, 1); + t.equal(rotateend.callCount, 0); + + // simulates another handler taking over map.stop(); - simulate.mousemove(map.getCanvas(), {buttons: 2, clientX: 12, clientY: 10}); - simulate.mousemove(map.getCanvas(), {buttons: 2, clientX: 14, clientY: 10}); + t.equal(rotatestart.callCount, 1); + t.equal(rotate.callCount, 1); + t.equal(rotateend.callCount, 0); + + simulate.mousemove(map.getCanvas(), {buttons: 2}); map._updateCamera(); - t.equalWithPrecision(map.getBearing(), initialBearing + 3.2, 1e-6); + t.equal(rotatestart.callCount, 1); + t.equal(rotate.callCount, 2); + t.equal(rotateend.callCount, 0); + + simulate.mouseup(map.getCanvas(), {buttons: 0, button: 2}); + map._updateCamera(); + t.equal(rotatestart.callCount, 1); + t.equal(rotate.callCount, 2); + t.equal(rotateend.callCount, 1); map.remove(); t.end();