The problem I have here is when I try to implement the audio is that it keeps on playing every second, I have included the source for the audio code at the very bottom if you may need it.
let time = startingMinutes * 60;
const countdownEl = document.getElementById('Countdown');
setInterval(updateCountdown, 1000);
function updateCountdown () {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds <10 ? '0' + seconds : seconds;
countdownEl.innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
}
const audio = new Audio();
audio.src = "alarm.mp3"; ```
You need to clear setInterval once timer reaches 0 and also need to put the audio code inside updateCountdown function when timer reaches 0. Additionally you can use a global variable to track if audio is played or not and use it conditionally. Check the code.
document.addEventListener('DOMContentLoaded', function() {
let startingMinutes = 1; // one min
let time = startingMinutes * 60;
var audioPlayed = false; // audio is not played - create a global variable to track if audio is already played (optional)
const countdownEl = document.getElementById('Countdown');
const counterInterval = setInterval(updateCountdown, 1000);
function updateCountdown () {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds <10 ? '0' + seconds : seconds;
countdownEl.innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if(!time && !audioPlayed) {
const statusEl = document.getElementById('Status');
var status = "timer reaches 0";
// prefered - clear interval, so once timer reaches zero, there will be no more call to updateCountdown
clearInterval(counterInterval);
status += ", clear setInterval";
// this is optional, in case the code above not work for any reason
// set the global var audioPlayed to true to indicate audio is played
audioPlayed = true;
status += ", audio play starts";
Status.innerHTML = status;
// run your audio
// const audio = new Audio();
// audio.src = "alarm.mp3";
}
}
});
<html>
<span id="Countdown"></span> <span id="Status"></span>
</html>
For the people viewing this question and would like an answer. Please note this audio will keep on playing as the timer stays at 0
const startingMinutes= 1;
let time = startingMinutes * 60;
const countdownEl = document.getElementById('Countdown');
setInterval(updateCountdown, 1000);
function updateCountdown () {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds <10 ? '0' + seconds : seconds;
countdownEl.innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (time <=0) {audio.play()};
}
const audio = new Audio();
audio.src = "alarm.mp3";
Related
I have a timer and a time. The time format is like the currentTime variable in my code. I want to get the currentTime time and add +1 to it every second keeping the same time format. Also I would like to subtract the currentTime + 1 - the total hours but keeping it real time with setInterval. Hope I am clear about my questions. Thanks.
HTML
<button id="start">START</button>
<button id="pause">PAUSE</button>
<div id="output"></div>
Javscript
const startTimeButton = document.querySelector("#start")
const pauseTimeButton = document.querySelector("#pause")
const output = document.querySelector("#output");
let currentTime = "12: 42: 17";
let totalHours = 30;
let seconds = 0;
let interval = null;
const timer = () => {
seconds++;
// Get hours
let hours = Math.floor(seconds / 3600);
// Get minutes
let minutes = Math.floor((seconds - hours * 3600) / 60);
// Get seconds
let secs = Math.floor(seconds % 60);
if (hours < 10) {
hours = `0${hours}`;
}
if (minutes < 10) {
minutes = `0${minutes}`;
}
if (secs < 10) {
secs = `0${secs}`;
}
return `${hours}:${minutes}:${secs}`;
};
startTimeButton.addEventListener("click", () => {
pauseTimeButton.style.display = "flex";
startTimeButton.style.display = "none";
console.log("START TIME CLICKED");
if (interval) {
return;
}
interval = setInterval(timer, 1000);
});
pauseTimeButton.addEventListener("click", () => {
pauseTimeButton.style.display = "none";
startTimeButton.style.display = "flex";
console.log("PAUSE TIME CLICKED");
clearInterval(interval);
interval = null;
});
// Here is an example of what I would like to achive
// currentTime + 1 (each second)
// output.innerHTML = (parseInt(currentTime) + 1) - totalHours;
Summary of my program:
The user speaks to the computer for 8 minutes (there is a countdown function too) - a button is clicked to initiate speech recognition and the countdown timer
When 8 minutes is reached, speech recognition stops
There is a 10 second delay/pause and then speech recognition continues again (without the user needing to initiate speech recognition by themselves) and the user speaks to the computer for another 2 minutes (once minutes and seconds == 0, speech recognition stops again).
My code:
//HTML STUFF
<html>
<button id="speak_button">Click</button> //button that when clicked triggers speech recognition
<div id="circle"><p id="countdown">8:00</p></div> // circle showing countdown from 8 minutes
</html>
//SPEECH RECOGNITION STUFF
<script>
let isListening = false;
window.addEventListener('DOMContentLoaded', function() {
document.getElementById("speak_button").addEventListener('click', function() {
if (isListening) {
console.log('STOPPING RECOGNITION');
isListening = false;
recognition.stop();
} else {
console.log('STARTING RECOGNITION');
recognition.start();
setInterval(updateCountDown,1000); //So the updateCountDown function occurs 1 second after clicking
updateCountDown();
isListening = true;
}
});
});
//COUNTDOWN FUNCTION
const startingMinutes = 8;
let time = startingMinutes * 60;
function updateCountDown() {
document.getElementById("countdown").innerHTML = "8:00";
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 8 ? '0' + seconds : seconds;
document.getElementById("countdown").innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (minutes == 0 && seconds == 0) {
recognition.abort();
isListening = false;
}
};
<script>
Once the countdown timer reaches 0 (once the 8 minutes is complete), I want there to be a 10 second pause for the user and then they have a further 2 minutes of speaking! I tried using a setTimeout function both inside and outside the if statement below but that doesn't seem to work!
function updateCountDown() {
document.getElementById("countdown").innerHTML = "8:00";
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 8 ? '0' + seconds : seconds;
document.getElementById("countdown").innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (minutes == 0 && seconds == 0) {
recognition.abort();
isListening = false;
setTimeout(updateCountDownNew, 10,000); //SET TIMEOUT FUNCTION TRIAL
//updateCountDownNew is the same function as updateCountDown but runs for 2 minutes!
}
};
//updateCountDownNew function is below
function updateCountDownNew() {
const startingMinutes = 2;
let time = startingMinutes * 60;
isListening = true;
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 2 ? '0' + seconds : seconds;
document.getElementById("countdown").innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (minutes == 0 && seconds == 0) {
recognition.abort();
isListening = false;
}
};
If anyone has any advice that would be great!
I am trying to find a way to restart my countdown timer at 2:00 again when it reaches 0:00. I don't know if I'm wrong, but it won't work.
const startingMinutes = 2;
let time = startingMinutes * 60;
const countdownEl = document.getElementById('countdown');
setInterval(updateCountdown, 1000)
function updateCountdown(){
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 10 ? '0' + seconds : seconds;
countdownEl.innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (time == 0) {
fn();
setInterval(updateCountdown, 1000)
return;
}
}
<p id="countdown">2:00</p>
Reset the time once it hits zero, and you don't need to call setInterval again. Also, by calling updateCountdown() directly we can avoid hardcoding 2:00 in the HTML.
const startingMinutes = 2;
let time = startingMinutes * 60;
const countdownEl = document.getElementById('countdown');
function updateCountdown(){
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 10 ? '0' + seconds : seconds;
countdownEl.innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (time == 0) {
// fn(); <-- not sure what this is supposed to do, so I commented it out
time = startingMinutes * 60; // reset counter
}
}
setInterval(updateCountdown, 1000);
updateCountdown();
<p id="countdown"></p>
Just reset your time:
Sample
var startingMinutes = 2;
let time = startingMinutes * 60;
const countdownEl = document.getElementById('countdown');
setInterval(updateCountdown, 1000)
function updateCountdown() {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 10 ? '0' + seconds : seconds;
countdownEl.innerHTML = `${minutes}:${seconds}`;
time--;
time = time < 0 ? 0 : time;
if (time == 0) {
fn();
time = startingMinutes * 60;
return;
}
function fn() {
console.log("timer reset");
}
}
<p id="countdown">2:00</p>
Slightly different methodology.
window.addEventListener('load', ticker(120, countdown('countdown')))
function countdown(target) {
let counter = document.getElementById(target)
return (now) => {
let minutes = Math.floor(now / 60)
let seconds = Math.round((now / 60) % 1 * 60)
seconds = seconds >= 0 && seconds < 10 ? seconds = '0'+seconds : seconds
counter.textContent = minutes+':'+seconds
}
}
function ticker(seconds, tick, step = 1000) {
let now = seconds;
(function next() {
tick(now)
now = now - 1 || seconds
setTimeout(next, step)
})()
}
<p id="countdown">Loading...</p>
Here is a simple timer, how would I implement clearInterval() in this bit of code when the timer reaches 0? It currently is infinite.
const start = 0.1; //6 seconds
let time = start * 60;
const count = document.querySelector('#countdown-timer');
const interval = setInterval(updateTimer, 1000);
function updateTimer() {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 10 ? '0' + seconds : seconds;
count.innerHTML = `${minutes}:${seconds}`;
time--;
}
<span id="countdown-timer"></span>
Like this
Also you can simplify the padding
const start = 0.1; //6 seconds
let time = start * 60;
const count = document.querySelector('#countdown-timer');
const interval = setInterval(updateTimer, 1000);
function updateTimer() {
if (time<=0) clearInterval(interval)
const minutes = Math.floor(time / 60);
let seconds = time % 60;
count.innerHTML = `${minutes}:${String(seconds).padStart(2,'0')}`;
time--;
}
<span id="countdown-timer"></span>
I have a stopwatch for a small tool here, I received most of the code from a previous question and I was going about trying to implement it, I began breaking it down and trying to understand it.
So far I think I understand most of it (Still some bits I am researching); however I was trying to adapt the code to my tool.
My requirements:
A start/stop button (a single button) - the value will change depending on if the timer is running or not.
A reset button - this will simply reset the timer to 00:00:00 and if the tool is running it will also stop it.
So far, the reset button is not configured, this is fine. The start and stop button works; however say I stopped the timer, and then started it again without resetting it, the timer just begins at 00:00:00 again, it will not continue from where it was paused.
It would be greatly appreciated if anyone would be able to explain how I could do this? I have tried the following:
Storing 'differenceInMillis for each loop of updateTimer() in a global variable, then subtracting the value from startTime = Date.now() each time the timer is restarted (This was suggested by a user in a previous question), I could not get this to work.
The code I have so far -
HTML (buttons and clock):
const outputElement = document.getElementById("outputt");
var startTime = 0;
var running = 0;
var splitcounter = 0;
function startstop() {
if (running == 0) {
running = 1;
startTime = Date.now();
startstopbutton.value = 'Stop';
document.getElementById("outputt").style.backgroundColor = "#2DB37B";
updateTimer();
} else {
running = 0;
// logTime();
startstopbutton.value = 'Start';
document.getElementById("outputt").style.backgroundColor = "#B3321B";
}
}
function updateTimer() {
if (running == 1) {
let differenceInMillis = Date.now() - startTime;
let {
hours,
minutes,
seconds
} = calculateTime(differenceInMillis);
let timeStr = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
outputElement.innerText = timeStr;
requestAnimationFrame(updateTimer);
}
}
function calculateTime(milliS) {
const SECONDS = 1000; // should be 1000 - only 10 to speed up the timer
const MINUTES = 60;
const HOURS = 60;
const RESET = 60;
let hours = Math.floor(milliS / SECONDS / MINUTES / HOURS);
let minutes = Math.floor(milliS / SECONDS / MINUTES) % RESET;
let seconds = Math.floor(milliS / SECONDS) % RESET;
return {
hours,
minutes,
seconds
};
}
function pad(time) {
return time.toString().padStart(2, '0');
}
<input id="startstopbutton" class="buttonZ" style="width: 120px;" type="button" name="btn" value="Start" onclick="startstop();">
<input id="resetbutton" class="buttonZ" style="width: 120px;" type="button" name="btnRst" id='btnRst' value="Reset" onclick="resetclock();" />
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>
UPDATE new version - does not work however - session storage does not work at SO so will have to test elsewhere
const outputElement = document.getElementById("outputt");
var startTime = 0;
var running = 0;
var splitcounter = 0;
function startstop() {
if (running == 0) {
running = 1;
startTime = new Date(sessionStorage.getItem("time"))
if (isNaN(startTime)) startTime = Date.now();
startstopbutton.value = 'Stop';
document.getElementById("outputt").style.backgroundColor = "#2DB37B";
updateTimer();
} else {
running = 0;
logTime();
startstopbutton.value = 'Start';
document.getElementById("outputt").style.backgroundColor = "#B3321B";
}
}
function updateTimer() {
if (running == 1) {
let differenceInMillis = Date.now() - startTime;
sessionStorage.setItem("time", differenceInMillis)
let {
hours,
minutes,
seconds
} = calculateTime(differenceInMillis);
let timeStr = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
outputElement.innerText = timeStr;
requestAnimationFrame(updateTimer);
}
}
function calculateTime(milliS) {
const SECONDS = 1000; // should be 1000 - only 10 to speed up the timer
const MINUTES = 60;
const HOURS = 60;
const RESET = 60;
let hours = Math.floor(milliS / SECONDS / MINUTES / HOURS);
let minutes = Math.floor(milliS / SECONDS / MINUTES) % RESET;
let seconds = Math.floor(milliS / SECONDS) % RESET;
return {
hours,
minutes,
seconds
};
}
function pad(time) {
return time.toString().padStart(2, '0');
}
If you MUST use a date object, you will need to change
startTime = Date.now();
to
startTime = new Date(sessionStorage.getItem("time"))
if (isNaN(startTime)) startTime = Date.now();
and save the time
let differenceInMillis = Date.now() - startTime;
sessionStorage.setItem("time",differenceInMillis)
If not, use a counter instead of a date object
Also when you use a toggle as boolean, make it and use it as a boolean (good practice - not mandatory for this issue)
const outputElement = document.getElementById("outputt");
let counter = 0,
running = false,
splitcounter = 0,
lastTime = 0;
function startstop() {
running = !running;
startstopbutton.value = running ? 'Stop' : 'Start';
document.getElementById("outputt").style.backgroundColor = running ? "#2DB37B" : "#B3321B";
if (running) updateTimer(0)
}
function updateTimer(currentTime) {
if (running) requestAnimationFrame(updateTimer)
if (currentTime >= (lastTime + 1000)) {
counter++;
lastTime = currentTime;
let {
hours,
minutes,
seconds
} = calculateTime(counter * 1000);
let timeStr = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
outputElement.innerText = timeStr;
}
}
function calculateTime(milliS) {
const SECONDS = 1000; // should be 1000 - only 10 to speed up the timer
const MINUTES = 60;
const HOURS = 60;
const RESET = 60;
let hours = Math.floor(milliS / SECONDS / MINUTES / HOURS);
let minutes = Math.floor(milliS / SECONDS / MINUTES) % RESET;
let seconds = Math.floor(milliS / SECONDS) % RESET;
return {
hours,
minutes,
seconds
};
}
function pad(time) {
return time.toString().padStart(2, '0');
}
<input id="startstopbutton" class="buttonZ" style="width: 120px;" type="button" name="btn" value="Start" onclick="startstop();">
<input id="resetbutton" class="buttonZ" style="width: 120px;" type="button" name="btnRst" id='btnRst' value="Reset" onclick="resetclock();" />
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>