-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathanim-event.esm.js
116 lines (96 loc) · 2.44 KB
/
anim-event.esm.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
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
/* ================================================
DON'T MANUALLY EDIT THIS FILE
================================================ */
/*
* AnimEvent
* https://github.com/anseki/anim-event
*
* Copyright (c) 2021 anseki
* Licensed under the MIT license.
*/
var MSPF = 1000 / 60,
// ms/frame (FPS: 60)
KEEP_LOOP = 500,
/**
* @typedef {Object} task
* @property {Event} event
* @property {function} listener
*/
/** @type {task[]} */
tasks = [];
var requestAnim = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
return setTimeout(callback, MSPF);
},
cancelAnim = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame || function (requestID) {
return clearTimeout(requestID);
};
var lastFrameTime = Date.now(),
requestID;
function step() {
var called, next;
if (requestID) {
cancelAnim.call(window, requestID);
requestID = null;
}
tasks.forEach(function (task) {
var event;
if (event = task.event) {
task.event = null; // Clear it before `task.listener()` because that might fire another event.
task.listener(event);
called = true;
}
});
if (called) {
lastFrameTime = Date.now();
next = true;
} else if (Date.now() - lastFrameTime < KEEP_LOOP) {
// Go on for a while
next = true;
}
if (next) {
requestID = requestAnim.call(window, step);
}
}
function indexOfTasks(listener) {
var index = -1;
tasks.some(function (task, i) {
if (task.listener === listener) {
index = i;
return true;
}
return false;
});
return index;
}
var AnimEvent = {
/**
* @param {function} listener - An event listener.
* @returns {(function|null)} A wrapped event listener.
*/
add: function add(listener) {
var task;
if (indexOfTasks(listener) === -1) {
tasks.push(task = {
listener: listener
});
return function (event) {
task.event = event;
if (!requestID) {
step();
}
};
}
return null;
},
remove: function remove(listener) {
var iRemove;
if ((iRemove = indexOfTasks(listener)) > -1) {
tasks.splice(iRemove, 1);
if (!tasks.length && requestID) {
cancelAnim.call(window, requestID);
requestID = null;
}
}
}
};
export default AnimEvent;