@@ -5,65 +5,61 @@ export default class extends Controller {
55
66 connect ( ) {
77 // start the automatic timer display
8- this . startTimer ( ) ;
8+ const timer = requestAnimationFrame ( this . loop . bind ( this ) ) ;
9+ this . data . set ( 'timer' , timer ) ;
10+
11+ // keep a reference to the start time
12+ const startTime = Date . now ( ) ;
13+ this . data . set ( 'start-time' , startTime ) ;
914
1015 // hide the refresh link
1116 this . refreshTarget . style . display = 'none' ;
1217 }
1318
14- startTimer ( ) {
15- // read initial time
16- let initialTime = this . data . get ( 'elapsed' ) ;
17- initialTime = initialTime . split ( ':' ) ;
18- initialTime = initialTime . map ( number => {
19- return parseInt ( number ) ;
20- } ) ;
21-
22- // create a diy time object
23- this . currentTime = {
24- h : initialTime [ 0 ] ,
25- m : initialTime [ 1 ] ,
26- s : initialTime [ 2 ]
27- } ;
28-
29- // start timer loop
30- this . timer = setInterval ( ( ) => {
31- this . incrementTimer ( ) ;
32- this . updateDisplay ( ) ;
33- } , 1000 ) ;
19+ disconnect ( ) {
20+ // stop the animation loop
21+ const timer = parseInt ( this . data . get ( 'timer' ) ) ;
22+ cancelAnimationFrame ( timer ) ;
3423 }
3524
36- incrementTimer ( ) {
37- this . currentTime . s ++ ;
38-
39- if ( this . currentTime . s > 59 ) {
40- this . currentTime . s = 0 ;
41- this . currentTime . m ++ ;
25+ displayElapsedTime ( ms ) {
26+ // convert the elapsed milliseconds into seconds
27+ const totalInSeconds = ms / 1000 ;
28+ // how many seconds to display
29+ const s = parseInt ( totalInSeconds % 60 ) ;
30+ // how many minutes to display
31+ const m = Math . floor ( totalInSeconds / 60 ) % 60 ;
32+ // how many hours to display
33+ const h = Math . floor ( totalInSeconds / 60 / 60 ) ;
4234
43- if ( this . currentTime . m > 59 ) {
44- this . currentTime . m = 0 ;
45- this . currentTime . h ++ ;
46- }
47- }
35+ // convert to the string format: HH:MM:SS
36+ const displayTime = `${ this . pad ( h ) } :${ this . pad ( m ) } :${ this . pad ( s ) } ` ;
37+ // display the string
38+ this . elapsedTarget . innerHTML = displayTime ;
4839 }
4940
50- updateDisplay ( ) {
51- const hours = this . displayNumber ( this . currentTime . h ) ;
52- const minutes = this . displayNumber ( this . currentTime . m ) ;
53- const seconds = this . displayNumber ( this . currentTime . s ) ;
54- const elapsed = `${ hours } :${ minutes } :${ seconds } ` ;
55-
56- this . elapsedTarget . innerHTML = elapsed ;
57- this . data . set ( 'elapsed' , elapsed ) ;
41+ loop ( ms ) {
42+ // the loop keeps running itself; replace the reference each time
43+ const timer = requestAnimationFrame ( this . loop . bind ( this ) ) ;
44+ this . data . set ( 'timer' , timer ) ;
45+
46+ // get the elapsed time in milliseconds
47+ const now = Date . now ( ) ;
48+ const startTime = parseInt ( this . data . get ( 'start-time' ) ) ;
49+ const elapsed = now - startTime ;
50+
51+ // convert to human friendly format and display it
52+ this . displayElapsedTime ( elapsed ) ;
5853 }
5954
60- displayNumber ( number ) {
61- number = number . toString ( ) ;
55+ // convert number to string and ensure it is at least two characters long
56+ pad ( num ) {
57+ num = num . toString ( ) ;
6258
63- if ( number . length < 2 ) {
64- number = '0' + number ;
59+ if ( num . length < 2 ) {
60+ num = `0 ${ num } ` ;
6561 }
6662
67- return number ;
63+ return num ;
6864 }
6965}
0 commit comments