################## # UNDER THE HOOD # ################## VueJS (from <head>): <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> ^^^ Note: this the development version since this is only a demonstration <script type="text/javascript"> var curr_time = new Date() curr_time.setHours(0,0,0,0) var app = new Vue({ el: '#app', data: { ct_display: '00:00:00.000', user_time: null, user_unit: 'secs', time_units: [ {value: 'secs', text: 'seconds'}, {value: 'mins', text: 'minutes'}, {value: 'hrs', text: 'hours'} ], user_sound: 'birds', sounds: ['birds', 'chime', 'alarm'], curr_time: curr_time, inprog: 0, bt_start: true, bt_stop: false, audio: null }, // end of 'data' methods: { getBaseTime: function() { this.hours = this.curr_time.getHours() this.hours = this.hours < 10 ? '0'+this.hours : this.hours this.minutes = this.curr_time.getMinutes() this.minutes = this.minutes < 10 ? '0'+this.minutes : this.minutes this.seconds = this.curr_time.getSeconds() this.seconds = this.seconds < 10 ? '0'+this.seconds : this.seconds this.milliseconds = this.curr_time.getMilliseconds() if (this.milliseconds < 10) { this.milliseconds = '00'+this.milliseconds } else if (this.milliseconds < 100) { this.milliseconds = '0'+this.milliseconds } // display hh:mm:ss.mss in div innerText this.ct_display = this.hours + ':' + this.minutes + ':' + this.seconds + '.' + this.milliseconds // increment the hundredths place of milliseconds this.milliseconds = this.curr_time.setMilliseconds(this.curr_time.getMilliseconds() - 10) }, // end of 'getBaseTime' start: function() { let t_user_time = this.user_time if (this.user_time == null) { this.ct_display = 'Please enter a number' setTimeout(() => { this.reset() }, 2000) } else { if (this.inprog == 0) { t_user_time = t_user_time < 10 ? '0'+t_user_time : t_user_time if (this.user_unit == 'secs') { this.curr_time.setHours(0,0,this.user_time,0) } else if (this.user_unit == 'mins') { this.curr_time.setHours(0,this.user_time,0,0) } else if (this.user_unit == 'hrs') { this.curr_time.setHours(this.user_time,0,0,0) } else { console.log('something else happened') } this.user_time = '' this.startTimer() } else { this.startTimer() } this.bt_start = false this.bt_stop = true } }, // end of 'start' startTimer: function() { audio = new Audio('https://lar-mo.com/mp3s/' + this.user_sound + '.mp3') this.stopwatch = setInterval(() => { this.getBaseTime() if (this.ct_display == '00:00:00.000') { clearInterval(this.stopwatch) app.ct_display = "Time's up" this.bt_stop = false setTimeout(() => { this.reset() }, 2000) this.playAudio() } }, 10) this.inprog++ }, // end of 'startTimer' playAudio: function() { audio.play() }, // end of 'playAudio' stop: function() { clearInterval(this.stopwatch) this.bt_start = true this.bt_stop = false }, // end of 'stop' reset: function() { this.curr_time.setHours(0,0,0,0) this.ct_display = '00:00:00.000' this.input_time = null clearInterval(this.stopwatch) this.bt_start = true this.bt_stop = false if (this.inprog != 0) { this.stopAudio() } this.inprog = 0 }, // end of 'reset' realtime: function() { let t_user_time = this.user_time t_user_time = t_user_time < 10 ? '0'+t_user_time : t_user_time if (this.user_unit == 'secs') { console.log('user unit is secs') this.ct_display = '00:00:'+t_user_time+'.000' } else if (this.user_unit == 'mins') { console.log('user unit is mins') this.ct_display = '00:'+t_user_time+':00.000' } else if (this.user_unit == 'hrs') { console.log('user unit is hrs') this.ct_display = t_user_time+':00:00.000' } else { console.log('something else happened') } }, // end of 'realtime' isNumber: function(evt) { evt = (evt) ? evt : window.event; var charCode = (evt.which) ? evt.which : evt.keyCode; if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) { evt.preventDefault();; } else { return true; } } // end of 'isNumber' }, // end of 'methods' computed: { isDisabled_start: function() { return !this.bt_start }, isDisabled_stop: function() { return !this.bt_stop } } // end of 'computed' }) // end of vue 'app' </script>