Timer.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. if ( this._usePageVisibilityAPI === true && document.hidden === true ) {
  41. this._delta = 0;
  42. } else {
  43. this._previousTime = this._currentTime;
  44. this._currentTime = ( timestamp !== undefined ? timestamp : now() ) - this._startTime;
  45. this._delta = ( this._currentTime - this._previousTime ) * this._timescale;
  46. this._elapsed += this._delta; // _elapsed is the accumulation of all previous deltas
  47. }
  48. return this;
  49. }
  50. }
  51. class FixedTimer extends Timer {
  52. constructor( fps = 60 ) {
  53. super();
  54. this._delta = ( 1 / fps ) * 1000;
  55. }
  56. update() {
  57. this._elapsed += ( this._delta * this._timescale ); // _elapsed is the accumulation of all previous deltas
  58. return this;
  59. }
  60. }
  61. function now() {
  62. return ( typeof performance === 'undefined' ? Date : performance ).now();
  63. }
  64. function handleVisibilityChange() {
  65. if ( document.hidden === false ) this.reset();
  66. }
  67. export { Timer, FixedTimer };