-
Notifications
You must be signed in to change notification settings - Fork 18
/
DemoTappable.js
81 lines (75 loc) · 2.56 KB
/
DemoTappable.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import TinyGesture from './dist/TinyGesture.js';
import { addTransition, removeTransition } from './DemoTransitions.js';
/**
* This function can be used as a Svelte action.
*/
export default function Tappable(
node,
options = {
bgColor: 'transparent',
color: 'black',
},
) {
const gesture = new TinyGesture(node);
let tapTimeout;
let pressTimeout;
// This prevents the 'tap' handler from firing on a long press.
let pressed = false;
addTransition(node, 'background-color .3s ease');
addTransition(node, 'color .3s ease');
// Note: don't use the 'tap' event to detect when the user has finished a long press, because it doesn't always fire.
gesture.on('tap', () => {
// If the user long pressed or pinched, don't run the tap handler. This event fires after the user lifts their finger.
if (pressed || gesture.scale > 1.1 || gesture.scale < 0.9) {
return;
}
// Embiggen.
node.style.transform = 'perspective(1000px) translate3d(0, 0, 100px)';
clearTimeout(tapTimeout);
tapTimeout = setTimeout(() => (node.style.transform = ''), 300);
});
gesture.on('doubletap', () => {
// Embiggen extra cromulently.
node.style.transform = 'perspective(1000px) translate3d(0, 0, 400px)';
clearTimeout(tapTimeout);
tapTimeout = setTimeout(() => (node.style.transform = ''), 300);
});
gesture.on('longpress', () => {
// Indicate that this is a long press. This event fires before the user lifts their finger.
pressed = true;
// If the user pinched, don't run the handler.
if (gesture.scale > 1.1 || gesture.scale < 0.9) {
return;
}
// Change colors.
node.style.backgroundColor = options.bgColor;
node.style.color = options.color;
clearTimeout(pressTimeout);
});
gesture.on('panend', () => {
// This is how you would detect when the user has finished a long press, because 'panend' will always fire, even if
// the user has moved their finger a little after 'longpress' has fired.
if (pressed) {
pressTimeout = setTimeout(() => {
node.style.backgroundColor = '';
node.style.color = '';
}, 300);
// Make sure to reset pressed after the current event loop.
setTimeout(() => {
pressed = false;
}, 0);
}
});
return {
destroy() {
clearTimeout(tapTimeout);
clearTimeout(pressTimeout);
node.style.transform = '';
node.style.backgroundColor = '';
node.style.color = '';
removeTransition(node, 'background-color');
removeTransition(node, 'color');
gesture.destroy();
},
};
}