114 lines
2.5 KiB
JavaScript
114 lines
2.5 KiB
JavaScript
import CetraPlugin from './CetraPlugin';
|
|
|
|
export default class Timing extends CetraPlugin {
|
|
static timers = new Map();
|
|
static animationFrameId;
|
|
static previousTimestamp;
|
|
|
|
#pluginName = 'timing';
|
|
|
|
#uniqueId;
|
|
|
|
constructor() {
|
|
super();
|
|
this.#uniqueId = Symbol('timer');
|
|
}
|
|
|
|
/**
|
|
* Clears all active timers.
|
|
*
|
|
* @static
|
|
* @memberof Cetra
|
|
* @returns {void}
|
|
*/
|
|
static #clearAllTimers() {
|
|
Cetra.timers.clear();
|
|
cancelAnimationFrame(Cetra.animationFrameId);
|
|
Cetra.animationFrameId = null;
|
|
}
|
|
|
|
/**
|
|
* gets called each tick the animationframe runs
|
|
* @memberof Cetra
|
|
* @static
|
|
* @method
|
|
* @param {Number} timestamp - the current timestamp of the animationframe
|
|
*/
|
|
static #update(timestamp) {
|
|
const elapsed = timestamp - Cetra.previousTimestamp;
|
|
Cetra.previousTimestamp = timestamp;
|
|
|
|
Cetra.timers.forEach((timer, timerId) => {
|
|
timer.timing -= elapsed;
|
|
|
|
if (timer.timing <= 0) {
|
|
timer.callback(elapsed / 1_000);
|
|
|
|
if (timer.loop) {
|
|
timer.timing = timer.interval;
|
|
} else {
|
|
Cetra.timers.delete(timerId);
|
|
}
|
|
}
|
|
});
|
|
|
|
if (Cetra.timers.size > 0) {
|
|
Cetra.animationFrameId = requestAnimationFrame(Cetra.update);
|
|
} else {
|
|
Cetra.animationFrameId = null;
|
|
}
|
|
}
|
|
|
|
register() {
|
|
Cetra.#clearAllTimers();
|
|
}
|
|
|
|
initComponent(el) {
|
|
// <div data-ctra-timer="name:delay:loops"></div>
|
|
}
|
|
|
|
/**
|
|
* Starts a timer with the specified callback function, interval, and loop flag.
|
|
*
|
|
* @static
|
|
* @memberof Cetra
|
|
* @param {Function} callback - The callback function to be executed on each timer tick.
|
|
* @param {number} interval - The interval (in milliseconds) between each timer tick.
|
|
* @param {boolean} [loop=false] - A flag indicating whether the timer should loop indefinitely.
|
|
* @returns {Symbol} The unique timer identifier.
|
|
*/
|
|
static startTimer(callback, interval, loop = false) {
|
|
const timerId = Symbol('timer');
|
|
Cetra.timers.set(timerId, {
|
|
callback,
|
|
interval,
|
|
loop,
|
|
timing: interval,
|
|
startTime: performance.now(),
|
|
});
|
|
|
|
if (!Cetra.animationFrameId) {
|
|
Cetra.previousTimestamp = performance.now();
|
|
Cetra.animationFrameId = requestAnimationFrame(Cetra.#update);
|
|
}
|
|
|
|
return timerId;
|
|
}
|
|
|
|
/**
|
|
* Clears the timer with the specified identifier.
|
|
*
|
|
* @static
|
|
* @memberof Cetra
|
|
* @param {Symbol} timerId - The unique identifier of the timer to be cleared.
|
|
* @returns {void}
|
|
*/
|
|
static clearTimer(timerId) {
|
|
Cetra.timers.delete(timerId);
|
|
if (Cetra.timers.size === 0) {
|
|
cancelAnimationFrame(Cetra.animationFrameId);
|
|
Cetra.animationFrameId = null;
|
|
}
|
|
}
|
|
}
|