Skip to content

Commit

Permalink
Allow very small twodrag and pinch gestures
Browse files Browse the repository at this point in the history
Before this commit, we strictly required the user to make a ~50 pixel
move in order to get these two gestures. We can get a more precise
experience if we allow very small gestures as well. This can be achieved
by making better use of our "_twoTouchTimeout".

Our two touch timeout handling was written to handle this well anyway.
We can distinguish between drag and pinch using the angle.
  • Loading branch information
samhed committed Mar 3, 2024
1 parent 786aba6 commit b5a6c36
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 24 deletions.
25 changes: 13 additions & 12 deletions core/input/gesturehandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,14 @@ export default class GestureHandler {
}

if (!this._hasDetectedGesture()) {
// Ignore moves smaller than the minimum threshold
if (Math.hypot(deltaX, deltaY) < GH_MOVE_THRESHOLD) {
return;
}

// Can't be a tap or long press as we've seen movement
this._state &= ~(GH_ONETAP | GH_TWOTAP | GH_THREETAP | GH_LONGPRESS);
this._stopLongpressTimeout();
let deltaMove = Math.hypot(deltaX, deltaY);

// Can't be a tap or long press if we've seen movement
if (deltaMove >= GH_MOVE_THRESHOLD) {
this._state &= ~(GH_ONETAP | GH_TWOTAP | GH_THREETAP | GH_LONGPRESS);
this._stopLongpressTimeout();
}

if (this._tracked.length !== 1) {
this._state &= ~(GH_DRAG);
Expand All @@ -213,10 +213,10 @@ export default class GestureHandler {
let prevDeltaMove = Math.hypot(prevTouch.firstX - prevTouch.lastX,
prevTouch.firstY - prevTouch.lastY);

// We know that the current touch moved far enough,
// but unless both touches moved further than their
// threshold we don't want to disqualify any gestures
if (prevDeltaMove > GH_MOVE_THRESHOLD) {
// Unless both touches moved further than their threshold we
// don't want to disqualify any gestures right now
if (deltaMove > GH_MOVE_THRESHOLD &&
prevDeltaMove > GH_MOVE_THRESHOLD) {

// The angle difference between the direction of the touch points
let deltaAngle = Math.abs(touch.angle - prevTouch.angle);
Expand All @@ -234,7 +234,8 @@ export default class GestureHandler {
}
} else if (!this._isTwoTouchTimeoutRunning()) {
// We can't determine the gesture right now, let's
// wait and see if more events are on their way
// wait and see if more events are on their way.
// If not, we'll have to decide which gesture it is.
this._startTwoTouchTimeout();
}
}
Expand Down
24 changes: 12 additions & 12 deletions tests/test.gesturehandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ describe('Gesture handler', function () {
touchStart(1, 50.0, 40.0);
touchStart(2, 60.0, 40.0);
touchMove(1, 80.0, 40.0);
touchMove(2, 110.0, 40.0);
touchMove(2, 90.0, 40.0);

expect(gestures).to.not.have.been.called;

Expand All @@ -603,15 +603,15 @@ describe('Gesture handler', function () {
detail: { type: 'twodrag',
clientX: 55.0,
clientY: 40.0,
magnitudeX: 40.0,
magnitudeX: 30.0,
magnitudeY: 0.0 } }));
});

it('should handle slow vertical two finger drag', function () {
touchStart(1, 40.0, 40.0);
touchStart(2, 40.0, 60.0);
touchMove(2, 40.0, 80.0);
touchMove(1, 40.0, 100.0);
touchMove(1, 40.0, 80.0);

expect(gestures).to.not.have.been.called;

Expand All @@ -633,14 +633,14 @@ describe('Gesture handler', function () {
clientX: 40.0,
clientY: 50.0,
magnitudeX: 0.0,
magnitudeY: 40.0 } }));
magnitudeY: 30.0 } }));
});

it('should handle slow diagonal two finger drag', function () {
touchStart(1, 50.0, 40.0);
touchStart(2, 40.0, 60.0);
touchMove(1, 70.0, 60.0);
touchMove(2, 90.0, 110.0);
touchMove(2, 60.0, 80.0);

expect(gestures).to.not.have.been.called;

Expand All @@ -661,8 +661,8 @@ describe('Gesture handler', function () {
detail: { type: 'twodrag',
clientX: 45.0,
clientY: 50.0,
magnitudeX: 35.0,
magnitudeY: 35.0 } }));
magnitudeX: 20.0,
magnitudeY: 20.0 } }));
});

it('should ignore too slow two finger drag', function () {
Expand Down Expand Up @@ -785,7 +785,7 @@ describe('Gesture handler', function () {
it('should handle pinching inwards slowly', function () {
touchStart(1, 0.0, 0.0);
touchStart(2, 130.0, 130.0);
touchMove(1, 50.0, 40.0);
touchMove(1, 30.0, 20.0);
touchMove(2, 100.0, 130.0);

expect(gestures).to.not.have.been.called;
Expand All @@ -807,14 +807,14 @@ describe('Gesture handler', function () {
detail: { type: 'pinch',
clientX: 65.0,
clientY: 65.0,
magnitudeX: 50.0,
magnitudeY: 90.0 } }));
magnitudeX: 70.0,
magnitudeY: 110.0 } }));
});

it('should handle pinching outwards slowly', function () {
touchStart(1, 100.0, 130.0);
touchStart(2, 110.0, 130.0);
touchMove(2, 200.0, 130.0);
touchMove(2, 130.0, 130.0);

expect(gestures).to.not.have.been.called;

Expand All @@ -835,7 +835,7 @@ describe('Gesture handler', function () {
detail: { type: 'pinch',
clientX: 105.0,
clientY: 130.0,
magnitudeX: 100.0,
magnitudeX: 30.0,
magnitudeY: 0.0 } }));
});

Expand Down

0 comments on commit b5a6c36

Please sign in to comment.