Skip to content

Commit

Permalink
Alternate fix for #6113
Browse files Browse the repository at this point in the history
  • Loading branch information
jfirebaugh committed Feb 16, 2018
1 parent 7afc072 commit 1af24ba
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 57 deletions.
18 changes: 3 additions & 15 deletions src/ui/handler/drag_pan.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
}

/**
Expand Down
36 changes: 10 additions & 26 deletions src/ui/handler/drag_rotate.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ class DragRotateHandler {
'_onDown',
'_onMove',
'_onUp',
'_onDragFrame',
'_onDragFinished'
'_onDragFrame'
], this);
}

Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
42 changes: 34 additions & 8 deletions test/unit/ui/handler/drag_pan.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
43 changes: 35 additions & 8 deletions test/unit/ui/handler/drag_rotate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 1af24ba

Please sign in to comment.