This repository has been archived on 2025-03-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
cetra/lib/plugins/Timing.js

114 lines
2.5 KiB
JavaScript
Raw Permalink Normal View History

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;
}
}
}