Skip to content

Instantly share code, notes, and snippets.

@Maksclub
Last active November 20, 2023 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Maksclub/d2f060c4364c6a66e4e351882379352f to your computer and use it in GitHub Desktop.
Save Maksclub/d2f060c4364c6a66e4e351882379352f to your computer and use it in GitHub Desktop.
import {BehaviorSubject, Observable, Subject} from "rxjs";
import {Injectable} from "@angular/core";
import {filter} from "rxjs/operators";
@Injectable()
export class PerformanceTimer {
private _currentTime$ = new BehaviorSubject<number>(0)
private timer: number | null = null;
private timeLimit = 0;
private unlimit = false;
private stopped = true;
public currentTime$() {
return this._currentTime$.asObservable()
}
public finishLimit$ = new Subject<void>()
public getCurrentTime(): number {
if (this._currentTime$ === undefined) {
throw Error('Must be init with init() method')
}
return this._currentTime$.value
}
init(timeLimit: number, unlimit: boolean = false) {
this.unlimit = unlimit
this.timeLimit = timeLimit
this._currentTime$.next(0)
}
continue = () => {
if (this._currentTime$ === undefined) {
throw Error('Must be init with init() method')
}
this.loop()
}
start = () => {
if (this._currentTime$ === undefined) {
throw Error('Must be init with init() method')
}
this.stopped = false
this.loop()
}
private loop = () => {
if (this._currentTime$ === undefined) {
throw Error('Must be init with init() method')
}
if (this.stopped) {
return
}
this.stop();
let lastTimestamp = performance.now();
const update = () => {
const time = performance.now();
this._currentTime$.next(this._currentTime$.value + (time - lastTimestamp))
lastTimestamp = time;
if (this._currentTime$.value >= this.timeLimit ) {
this.finishLimit$.next()
this.stop()
return
}
if (this._currentTime$.value < this.timeLimit || this.unlimit) {
this.timer = requestAnimationFrame(update);
}
}
this.timer = requestAnimationFrame(update);
};
stop = () => {
if (this._currentTime$ === undefined) {
throw Error('Must be init with init() method')
}
this._currentTime$.next(0)
this.stopped = true
if (this.timer) {
cancelAnimationFrame(this.timer);
this.timer = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment