blob: abe7f9bdb5d01a371997b1fc0fbbbd8c8c2989ad [file] [log] [blame]
Copybara botbe50d492023-11-30 00:16:42 +01001'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6var MIN_INERVAL = 1000 / 60;
7
8/**
9 * Trigger a callback at a given interval
10 * @param interval defaults to 1000/60 ms
11 * @return {function()} reference to start, stop, immediate and started
12 */
13
14var intervalFunction = function intervalFunction() {
15 var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MIN_INERVAL;
16
17
18 var lapse = interval < MIN_INERVAL ? MIN_INERVAL : interval;
19 var cb = undefined;
20 var next = null;
21 var timeElapsed = 0;
22
23 var execute = function execute() {
24 var f = cb(timeElapsed);
25 if (!f) {
26 cancel();
27 }
28 };
29
30 var cancel = function cancel() {
31 if (next) {
32 window.cancelAnimationFrame(next);
33 }
34 next = null;
35 timeElapsed = 0;
36 };
37
38 var _start = function _start() {
39 var timeStart = Date.now();
40
41 var loop = function loop(now) {
42 if (next) {
43 next = window.requestAnimationFrame(function () {
44 return loop(Date.now());
45 });
46
47 timeElapsed += now - timeStart;
48
49 if (timeElapsed >= lapse) {
50 execute();
51 if ((timeElapsed -= lapse) > lapse) {
52 // time elapsed - interval_ > interval_ , indicates inactivity
53 // Could be due to browser minimized, tab changed, screen saver started, computer sleep, and so on
54 timeElapsed = 0;
55 }
56 }
57 timeStart = now;
58 }
59 };
60
61 next = 1; // a truthy value for first loop
62 loop(timeStart);
63 };
64
65 return {
66 get started() {
67 return next != null;
68 },
69 get interval() {
70 return lapse;
71 },
72 set interval(value) {
73 lapse = value < MIN_INERVAL ? MIN_INERVAL : value;
74 },
75 start: function start(callback) {
76 if (typeof callback !== 'function') {
77 throw new TypeError('callback parameter must be a function');
78 }
79 cb = callback;
80 _start();
81 },
82 immediate: function immediate() {
83 if (!cb) {
84 throw new ReferenceError('callback parameter is not defined. Call start before immediate.');
85 }
86 execute();
87 },
88
89 stop: function stop() {
90 return cancel();
91 }
92 };
93};
94
95exports.default = intervalFunction;
96module.exports = exports['default'];