Timer.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. class Timer {
  2. constructor() {
  3. this._previousTime = 0;
  4. this._currentTime = 0;
  5. this._startTime = now();
  6. this._delta = 0;
  7. this._elapsed = 0;
  8. this._timescale = 1;
  9. // use Page Visibility API to avoid large time delta values
  10. this._usePageVisibilityAPI = ( typeof document !== 'undefined' && document.hidden !== undefined );
  11. if ( this._usePageVisibilityAPI === true ) {
  12. this._pageVisibilityHandler = handleVisibilityChange.bind( this );
  13. document.addEventListener( 'visibilitychange', this._pageVisibilityHandler, false );
  14. }
  15. }
  16. getDelta() {
  17. return this._delta / 1000;
  18. }
  19. getElapsed() {
  20. return this._elapsed / 1000;
  21. }
  22. getTimescale() {
  23. return this._timescale;
  24. }
  25. setTimescale( timescale ) {
  26. this._timescale = timescale;
  27. return this;
  28. }
  29. reset() {
  30. this._currentTime = now() - this._startTime;
  31. return this;
  32. }
  33. dispose() {
  34. if ( this._usePageVisibilityAPI === true ) {
  35. document.removeEventListener( 'visibilitychange', this._pageVisibilityHandler );
  36. }
  37. return this;
  38. }
  39. update( timestamp ) {
  40. this._previousTime = this._currentTime;
  41. this._currentTime = ( timestamp !== undefined ? timestamp : now() ) - this._startTime;
  42. this._delta = ( this._currentTime - this._previousTime ) * this._timescale;
  43. this._elapsed += this._delta; // _elapsed is the accumulation of all previous deltas
  44. return this;
  45. }
  46. }
  47. class FixedTimer extends Timer {
  48. constructor( fps = 60 ) {
  49. super();
  50. this._delta = ( 1 / fps ) * 1000;
  51. }
  52. update() {
  53. this._elapsed += ( this._delta * this._timescale ); // _elapsed is the accumulation of all previous deltas
  54. return this;
  55. }
  56. }
  57. function now() {
  58. return ( typeof performance === 'undefined' ? Date : performance ).now();
  59. }
  60. function handleVisibilityChange() {
  61. if ( document.hidden === false ) this.reset();
  62. }
  63. export { Timer, FixedTimer };