forked from jaammees/lvllvl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathripplejs.js
More file actions
129 lines (113 loc) · 3.41 KB
/
ripplejs.js
File metadata and controls
129 lines (113 loc) · 3.41 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
var rippleTypeAttr = 'data-event';
/**
* @param {!Event|!Touch} event
* @return {Node}
*/
function getHolderWithRippleJsClass(event, className) {
var rippleClassName = 'rippleJS';
if(typeof className != 'undefined') {
rippleClassName = className;
}
var holder = /** @type {!Node} */ (event.target);
var childNodesLength = holder.childNodes.length;
if (holder.localName !== 'button' || !childNodesLength) {
return holder.classList.contains(rippleClassName) ? holder : null;
}
// fix firefox event target issue https://bugzilla.mozilla.org/show_bug.cgi?id=1089326
for (var i = 0; i < childNodesLength; ++i) {
var child = holder.childNodes[i];
var cl = child.classList;
if (cl && cl.contains(rippleClassName)) {
return child; // return valid holder
}
}
return null;
}
/**
* @param {string} type
* @param {!Event|!Touch} at
*/
function startRipple(type, at, manualHolder) {
var holder = null;
if(typeof manualHolder != 'undefined') {
holder = manualHolder;
} else {
holder = getHolderWithRippleJsClass(at);
}
if (!holder) {
return false; // ignore
}
var cl = holder.classList;
// Store the event use to generate this ripple on the holder: don't allow
// further events of different types until we're done. Prevents double-
// ripples from mousedown/touchstart.
var prev = holder.getAttribute(rippleTypeAttr);
if (prev && prev !== type) {
return false;
}
holder.setAttribute(rippleTypeAttr, type);
// Create and position the ripple.
var rect = holder.getBoundingClientRect();
var x = at.offsetX;
var y;
if (x !== undefined) {
y = at.offsetY;
} else {
x = at.clientX - rect.left;
y = at.clientY - rect.top;
}
var ripple = document.createElement('div');
var max;
if (rect.width === rect.height) {
max = rect.width * 1.412;
} else {
max = Math.sqrt(rect.width * rect.width + rect.height * rect.height);
}
var dim = max*2 + 'px';
ripple.style.width = dim;
ripple.style.height = dim;
ripple.style.marginLeft = -max + x + 'px';
ripple.style.marginTop = -max + y + 'px';
// Activate/add the element.
ripple.className = 'ripple';
holder.appendChild(ripple);
window.setTimeout(function() {
ripple.classList.add('held');
}, 10);
var releaseEvent = (type === 'mousedown' ? 'mouseup' : 'touchend');
var release = function(ev) {
// TODO: We don't check for _our_ touch here. Releasing one finger
// releases all ripples.
document.removeEventListener(releaseEvent, release);
ripple.classList.add('done');
// larger than animation: duration in css
window.setTimeout(function() {
holder.removeChild(ripple);
if (!holder.children.length) {
cl.remove('active');
holder.removeAttribute(rippleTypeAttr);
}
}, 650);
};
document.addEventListener(releaseEvent, release);
}
/**
* Installs mousedown/touchstart handlers on the target for ripples.
*
* @param {!Node=} target to install on, default document
*/
function rippleJSInit(target) {
target = target || document;
target.addEventListener('mousedown', function(ev) {
if (ev.button === 0) {
// trigger on left click only
startRipple(ev.type, ev);
}
}, {passive: true});
target.addEventListener('touchstart', function(ev) {
for (var i = 0; i < ev.changedTouches.length; ++i) {
startRipple(ev.type, ev.changedTouches[i]);
}
}, {passive: true});
}
rippleJSInit();