Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow drag events to return to their original coords #1075

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions src/lib/is_click.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import euclideanDistance from './euclidean_distance';

const FINE_TOLERANCE = 4;
const GROSS_TOLERANCE = 12;
const TOLERANCE = 12;
const INTERVAL = 500;

export default function isClick(start, end, options = {}) {
const fineTolerance = (options.fineTolerance != null) ? options.fineTolerance : FINE_TOLERANCE;
const grossTolerance = (options.grossTolerance != null) ? options.grossTolerance : GROSS_TOLERANCE;
const interval = (options.interval != null) ? options.interval : INTERVAL;
const tolerance = options.tolerance || TOLERANCE;
const interval = options.interval || INTERVAL;

start.point = start.point || end.point;
start.time = start.time || end.time;
const moveDistance = euclideanDistance(start.point, end.point);
const startPoint = start.point || end.point;
const distance = euclideanDistance(startPoint, end.point);

return moveDistance < fineTolerance ||
(moveDistance < grossTolerance && (end.time - start.time) < interval);
const startTime = start.time || end.time;
const duration = end.time - startTime;

return distance < tolerance && duration < interval;
}
14 changes: 8 additions & 6 deletions src/lib/is_tap.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ export const TAP_TOLERANCE = 25;
export const TAP_INTERVAL = 250;

export default function isTap(start, end, options = {}) {
const tolerance = (options.tolerance != null) ? options.tolerance : TAP_TOLERANCE;
const interval = (options.interval != null) ? options.interval : TAP_INTERVAL;
const tolerance = options.tolerance || TAP_TOLERANCE;
const interval = options.interval || TAP_INTERVAL;

start.point = start.point || end.point;
start.time = start.time || end.time;
const moveDistance = euclideanDistance(start.point, end.point);
const startPoint = start.point || end.point;
const distance = euclideanDistance(startPoint, end.point);

return moveDistance < tolerance && (end.time - start.time) < interval;
const startTime = start.time || end.time;
const duration = end.time - startTime;

return distance < tolerance && duration < interval;
}
238 changes: 23 additions & 215 deletions test/is_click.test.js
Original file line number Diff line number Diff line change
@@ -1,235 +1,43 @@
import test from 'tape';
import isClick from '../src/lib/is_click';
import isClick from '../src/lib/is_tap';

// By adding these values as options and stating them in the test,
// we can know the calculation works from the tests, but tweak
// the actual constants in `is_click.js` without having to
// the actual constants in `is_tap.js` without having to
// rewrite tests.
const testOptions = {
fineTolerance: 4,
grossTolerance: 12,
interval: 500
tolerance: 12,
interval: 500,
};

test('isClick easy', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 1, y: 1},
time: 1
};
t.equal(isClick({}, b, testOptions), true, 'true when start is missing point and time');
t.equal(isClick({ time: 2000 }, b, testOptions), true, 'true when start has only time');
t.equal(isClick(a, b, testOptions), true, 'true when start and end match exactly');
t.end();
});

test('isClick when start/end have same time, very close coordinates', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 2, y: 1.5},
time: 1
};
t.equal(isClick(a, b, testOptions), true);
t.end();
});

test('isClick when start/end have same coordinates, distant times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 1, y: 1},
time: 6000
};
t.equal(isClick(a, b, testOptions), true);
t.end();
});

test('isClick when start/end have very close coordinates, distant times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 2, y: 1.15},
time: 6000
};
t.equal(isClick(a, b, testOptions), true);
t.end();
});


test('isClick when moving just under 4, same times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 3.8, y: 3.8 },
time: 1
};
// Move distance ~3.959798
t.equal(isClick(a, b, testOptions), true);
t.end();
});

test('isClick when moving just under 4, distant times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 3.8, y: 3.8 },
time: 6000
};
// Move distance ~3.959798
t.equal(isClick(a, b, testOptions), true);
t.end();
});

test('isClick when moving just above 4, same times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 3.9, y: 3.9},
time: 1
};
// Move distance ~4.101219
t.equal(isClick(a, b, testOptions), true);
t.end();
});

test('isClick when moving just above 4, very close times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 3.9, y: 3.9},
time: 499
};
// Move distance ~4.101219
t.equal(isClick(a, b, testOptions), true);
t.end();
});

test('isClick when moving just above 4, distant times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 3.9, y: 3.9},
time: 6000
};
// Move distance ~4.101219
t.equal(isClick(a, b, testOptions), false);
t.end();
});

test('isClick when moving just above 4, barely too distant times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 3.9, y: 3.9},
time: 501
};
// Move distance ~4.101219
t.equal(isClick(a, b, testOptions), false);
t.end();
});

test('isClick when moving just below 12, same times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 9.2, y: 9.2},
time: 1
};
// Move distance ~11.596551
t.equal(isClick(a, b, testOptions), true);
t.end();
});

test('isClick when moving just below 12, very close times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 9.2, y: 9.2},
time: 499
};
// Move distance ~11.596551
t.equal(isClick(a, b, testOptions), true);
t.end();
});
const start = { point: { x: 1, y: 1 }, time: 1 };
const pointInsideTolerence = { x: 9.2, y: 9.2}; // ~11.596551 from `start`
const pointOutsideTolerence = { x: 9.5, y: 9.5}; // ~12.020815 from `start`
const timeInsideInterval = 500; // 499 ms after `start`
const timeOutsideInterval = 502; // 501 ms after `start`

test('isClick when moving just below 12, distant times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 9.2, y: 9.2},
time: 6000
};
// Move distance ~11.596551
t.equal(isClick(a, b, testOptions), false);
test('isClick basics', (t) => {
const end = start;
t.equal(isClick({}, end, testOptions), true, 'true when start is missing point and time');
t.equal(isClick({ time: 2000 }, end, testOptions), true, 'true when start has only time');
t.equal(isClick(start, end, testOptions), true, 'true when start and end match exactly');
t.end();
});

test('isClick when moving just below 12, barely too distant times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 9.2, y: 9.2},
time: 501
};
// Move distance ~11.596551
t.equal(isClick(a, b, testOptions), false);
test('isClick when moving within the tolerated distance and duration', (t) => {
const end = { point: pointInsideTolerence, time: timeInsideInterval };
t.equal(isClick(start, end, testOptions), true);
t.end();
});

test('isClick when moving just above 12, same times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 9.5, y: 9.5},
time: 1
};
// Move distance ~12.020815
t.equal(isClick(a, b, testOptions), false);
test('!isClick when moving beyond the tolerated distance, and inside the tolerated duration', (t) => {
const end = { point: pointOutsideTolerence, time: timeInsideInterval };
t.equal(isClick(start, end, testOptions), false);
t.end();
});

test('isClick when moving just above 12, distant times', (t) => {
const a = {
point: { x: 1, y: 1 },
time: 1
};
const b = {
point: { x: 9.5, y: 9.5},
time: 6000
};
// Move distance ~12.020815
t.equal(isClick(a, b, testOptions), false);
test('!isClick when moving inside the tolerated distance, but beyond the tolerated duration', (t) => {
const end = { point: pointInsideTolerence, time: timeOutsideInterval };
t.equal(isClick(start, end, testOptions), false);
t.end();
});
Loading