async function play() { const number = document.getElementById("number").value; sayNumber(number); } async function sayNumber(number) { console.log(number) number = number.toString(); number = number.replace(/[^0-9]/, ""); for(let i = 0; i < number.length; i++) { await playAudio(document.getElementById(`sound-${number[i]}`)); } } function playAudio(audio){ return new Promise(res=>{ audio.play() audio.onended = res }) } function Timer() { return { time: 0, over: false, init() { setInterval(() => { const startedAt = Alpine.store("localState").startedAt; const resultTime = Alpine.store("localState").time; let time; if (!startedAt && !resultTime) { time = 0; this.over = false; } else if (resultTime) { time = (resultTime / 1000); this.over = true; } else { this.over = false; time = ((new Date().getTime() - startedAt) / 1000) ; } this.time = time.toFixed(2) }, 10); }, }; } document.addEventListener("alpine:init", () => { Alpine.store("localState", { _state: 0, // 0: idle // 1: starting // 2: running // 3: stopped startedAt: null, time: null, stateHint: "", init() { Alpine.effect(() => { switch(this._state) { case 0: { this.startedAt = null; this.time = null; this.stateHint = "Tap to start"; break; } case 1: { this.stateHint = "Get ready..." playAudio(document.getElementById("sound-ok-ready-go")).then(() => { Alpine.store("localState")._state = 2; }); break; } case 2: { this.stateHint = "Tap to stop" this.startedAt = new Date().getTime() - 200; break; } case 3: { this.stateHint = "Tap to reset" this.time = new Date().getTime() - this.startedAt; sayNumber((this.time / 1000).toFixed(2)); this.startedAt = null; break; } } }) }, next() { console.log("next"); playAudio(document.getElementById("sound-silence")) if(this._state == 1) return; this._state = (this._state + 1) % 4 }, }) })