After resetting stopwatch stopwatch is beginning at the previous time - javascript

When I want to reset my stopwatch and start it again the timer begins at the stop-point of the previous timer execution but I want that the timer begins at zero. I tried different ways to solve this problem but my tries did not work. What is my failure? The considered area in my JavaScript is marked up.
window.onload = function () {
//global variables
let interval = null;
let timerId = null;
let y = 3.90;
let reversal = 20
const output = document.querySelector('output');
let maintime = document.getElementById('maintime');
const start = document.getElementById('actioner');
const clear = document.getElementById('reseter');
let [milliseconds, seconds, minutes, hours] = [0, 0, 0, 0];
//If start is clicked
start.addEventListener('click', () => {
buttonAndTimer();
startDrive();
}); // end of func
function buttonAndTimer() {
start.innerText = 'Stop';
if (!interval) {
interval = setInterval(() => {
run();
}, 10);
} else {
clearInterval(interval)
start.innerText = 'Resume';
interval = null;
};
}
function run() {
milliseconds += 10;
if (milliseconds == 1000) { //note: 1000 milliseconds are 1 seconds
milliseconds = 0;
seconds++;
};
if (seconds == 60) {
seconds = 0;
minutes++;
};
if (minutes == 60) {
minutes == 0
hours++;
};
h = hours < 10 ? '0' + hours : hours;
m = minutes < 10 ? '0' + minutes : minutes;
s = seconds < 10 ? '0' + seconds : seconds;
ms = milliseconds < 100 ? '00' + milliseconds : milliseconds;
//Template Literals
maintime.innerHTML = `${h} : ${m} : ${s} : ${ms} `
};
//calculating price
function startDrive() {
if (start.innerText != 'Resume') {
output.innerHTML = y.toFixed(2) + '€';
timerId = setInterval(() => {
if (y < reversal) {
y += 0.14375;
} else if (y > reversal) {
y += 0.103125;
}
output.innerHTML = y.toFixed(2) + "€";
}, 5000);
}
/*Considered area */
if (start.innerText == 'Resume') {
clearInterval(timerId);
}
} //end of func
// considered area
clear.addEventListener('click', () => {
clearInterval(interval);
interval = null;
maintime.innerHTML = '00:00:00:000';
start.innerText = 'Start'
clearInterval(timerId);
timerId = 0;
output.innerHTML = "";
})
} //end of window.load
#box {
display: flex;
justify-content: center;
align-items:center;
flex-direction: column;
gap: 5px;
}
span, #maintime{
color:#74bde0;
width:15vh;
text-align: center;
max-width:20vh;
}
.button {
border:none;
border-radius: 30px;
cursor: pointer;
color:#74bde0;
box-shadow: 1px 1px 1px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}
output {
border: 1px solid;
border-color:#74bde0 ;
border-radius: 5px;
height: 10vh;
width: 30vh;
text-align: center;
color:#74bde0;
line-height: 500%;
box-shadow: rgba(17, 17, 26, 0.1) 0px 4px 16px, rgba(17, 17, 26, 0.1) 0px 8px 24px, rgba(17, 17, 26, 0.1) 0px 16px 56px;
}
#card {
background-color: #2f2f2f;
width: 80vh;
height: 10vh;
border:1px solid;
border-color:blueviolet;
border-radius: 30px;
}
<body>
<div id="box">
<button class='button' id='actioner'>Start</button>
<output></output>
<button class='button' id='reseter'>Reset</button>
<div id='mainstopwatch'>
<div id='maintime'>
<span class='span' id="mainhour">00:</span>
<span class='span' id="mainminute">00:</span>
<span class='span' id="mainsecond">00:</span>
<span class='span' id="milliseconds">000</span>
</div>
</div>
</body>

Fixed it.. I hope this is acceptable answer..
window.onload = function () {
//global variables
let interval = null;
let timerId = null;
let y = 3.90;
let reversal = 20
const output = document.querySelector('output');
let maintime = document.getElementById('maintime');
const start = document.getElementById('actioner');
const clear = document.getElementById('reseter');
let [milliseconds, seconds, minutes, hours] = [0, 0, 0, 0];
//If start is clicked
start.addEventListener('click', () => {
console.log("start clicked.. ")
buttonAndTimer();
startDrive();
}); // end of func
function buttonAndTimer() {
start.innerText = 'Stop';
if (!interval) {
interval = setInterval(() => {
run();
}, 10);
} else {
clearInterval(interval)
start.innerText = 'Resume';
interval = null;
};
}
function run() {
milliseconds += 10;
if (milliseconds == 1000) { //note: 1000 milliseconds are 1 seconds
milliseconds = 0;
seconds++;
};
if (seconds == 60) {
seconds = 0;
minutes++;
};
if (minutes == 60) {
minutes == 0
hours++;
};
h = hours < 10 ? '0' + hours : hours;
m = minutes < 10 ? '0' + minutes : minutes;
s = seconds < 10 ? '0' + seconds : seconds;
ms = milliseconds < 100 ? '00' + milliseconds : milliseconds;
//Template Literals
maintime.innerHTML = `${h} : ${m} : ${s} : ${ms} `
};
//calculating price
function startDrive() {
if (start.innerText != 'Resume') {
output.innerHTML = y.toFixed(2) + '€';
timerId = setInterval(() => {
if (y < reversal) {
y += 0.14375;
} else if (y > reversal) {
y += 0.103125;
}
output.innerHTML = y.toFixed(2) + "€";
}, 5000);
}
/*Considered area */
if (start.innerText == 'Resume') {
clearInterval(timerId);
}
} //end of func
// considered area
clear.addEventListener('click', () => {
console.log("clear clicked.. ")
clearInterval(interval);
interval = null;
maintime.innerHTML = '00:00:00:000';
start.innerText = 'Start'
clearInterval(timerId);
timerId = 0;
output.innerHTML = "";
milliseconds = 0
seconds = 0
minutes = 0
hours = 0
})
} //end of

Related

how to cancel pop up audio in javascript

hello I'm new to code and javascript I'm creating a clock with timer. the countdown is done well with an alarm and a pop up when the timer reaches zero. only I can't turn off the alarm when I close the pop up it opens in a loop. i need help please
let departInput = document.querySelector('#times');
let subButton = document.querySelector('#sub')
subButton.addEventListener('click', event => {
let temps = (departInput.value)*60;
var timerElement = document.getElementById("MyTimerDisplay")
setInterval(() => {
let minutes = parseInt(temps / 60, 10)
let secondes = parseInt(temps % 60, 10)
minutes = minutes < 10 ? "0" + minutes : minutes
secondes = secondes < 10 ? "0" + secondes : secondes
timerElement.innerText = `${minutes}:${secondes}`
temps = temps <= 0 ? 0 : temps - 1
if(minutes == 0 && secondes == 0){
var snd = new Audio('clock.mp3');
snd.play();
alert("cest l'heure")
}
}, 1000)
});
To address the problem you are having you should call clearTimer() when the alarm rings so that its callback won't be running again and again each second even after the condition to break was met.
Here's a working example to show the point:
let departInput = document.querySelector('#times');
let subButton = document.querySelector('#sub')
subButton.addEventListener('click', event => {
//decides how many minutes before the alarm rings
let minutesToAlarm = parseInt(departInput.value);
//initializes elapsedSeconds
let elapsedSeconds = minutesToAlarm*60;
var timerElement = document.getElementById("MyTimerDisplay");
var myTimer = setInterval(() => {
//converts elapsedSeconds in mm:ss format and refresh the ui
let minutes = Math.floor(elapsedSeconds/60);
let secondes = elapsedSeconds % 60;
timerElement.innerText = `${minutes}:${secondes}`
//decrement elapsedSeconds by 1
elapsedSeconds--;
if(elapsedSeconds === 0){
/*
* Part muted because there's no reference to clock.mp3
*
var snd = new Audio('clock.mp3');
snd.play();
*/
alert("cest l'heure");
//here clears the timer so that the callback
//won't be running again anymore
clearTimeout(myTimer);
}
}
, 1000);
});
#sub{
border: solid 1px black;
min-width: 5em;
padding: 2px;
cursor: pointer;
}
#MyTimerDisplay{
border: dashed 4px darkgray;
margin-top: 5px;
width: fit-content;
padding: 5px 20px;
}
<input id="times" type="text" placeholder="departInput"/>
<button id="sub">clickme</button>
<div id="MyTimerDisplay">#times</div>

Stop the audio player

I have an audio script with play/pause, I want to make the audio stop when I click on the square button at the left, and to add the timing to the right
here is the code: https://codepen.io/Amirafik/pen/YzxQZQw
HTML
<div class="title">
Dina Mohamed
</div>
<div class="stop"></div>
<div id="audioButton">
<div id="playerContainer">
<div class="listen">LISTEN</div>
</div>
</div>
<div class="duration">
00:12
</div>
<br>_____________________________________________________</br>
<div class="note">
<p>All items were more than perfect, we loved the experience and will order ONE OAK services again in the future for sure. <!--<span style="color:#F04E36"><br> Dina sent us an amazing feedback about her experience, tap the play button to listen to her cheerful words.</span></p>-->
</div
CSS
#import url('https://fonts.googleapis.com/css?family=montserrat:100,200,300,400,500,600,700,800,900');
body {
background: #ffffff;
color: #000000;
font-size: 16px ;
font-family: "montserrat" ;
font-weight: 500;
-webkit-tap-highlight-color: transparent;
}
a {
color: #F04E36;
}
.title {
max-width: 700px;
margin: 0 auto;
color: #000000;
font-weight:700;
display:inline-block;
}
.note {
max-width: 380px;
margin: 0 auto;
color: #000000;
display:inline-block;
}
.circle-audio-player {
cursor: pointer;
width:25px;
padding:0px;
margin-top:-67%;
margin-bottom:-50%;
margin-left:-7px;
background-color:#EDEBE7;
border-radius:50%;
vertical-align:middle;
}
#playerContainer {
padding: 0px;
vertical-align:middle;
}
#audioButton {
border-radius: 50px;
border: 2px solid #000000;
padding: 10px;
max-width: 85px;
height: 10px;
display: inline-block;
vertical-align:middle;
margin-left:2px;
}
.listen {
margin-left: 5px;
color: #000000;
font-weight:700;
display:inline-block;
float:right;
vertical-align:middle;
margin-top:-5%;
font-size: 14px ;
}
.stop {
max-width: 500px;
margin-left:10px;
height: 10px;
width: 10px;
background-color: #000000;
font-weight:500;
font-size: 14px ;
display:inline-block;
vertical-align:middle;
}
.duration {
max-width: 500px;
margin-left: 2px;
color: #000000;
font-weight:500;
font-size: 14px ;
display:inline-block;
}
JS
// settings
var DEFAULTS = {
borderColor: "#EDEBE7",
playedColor: "#F04E36",
backgroundColor: "#d3cdc2",
iconColor: "#000000",
borderWidth: 2,
size: 48,
className: 'circle-audio-player'
};
// reused values
var pi = Math.PI;
var doublePi = pi * 2;
var arcOffset = -pi / 2;
var animTime = 200;
var loaderTime = 1800;
var CircleAudioPlayer = function (options) {
options = options || {};
for (var property in DEFAULTS) {
this[property] = options[property] || DEFAULTS[property];
}
// create some things we need
this._canvas = document.createElement('canvas');
this._canvas.setAttribute('class', this.className + ' is-loading');
this._canvas.addEventListener('mousedown', (function () {
if (this.playing) {
this.pause();
}
else {
this.play();
}
}).bind(this));
this._ctx = this._canvas.getContext('2d');
// set up initial stuff
this.setAudio(options.audio);
this.setSize(this.size);
// redraw loop
(function cAPAnimationLoop (now) {
// check if we need to update anything
if (this.animating) {
this._updateAnimations(now);
}
if (this._forceDraw || this.playing || this.animating || this.loading) {
this._draw();
this._forceDraw = false;
}
requestAnimationFrame(cAPAnimationLoop.bind(this));
}).call(this, new Date().getTime());
};
CircleAudioPlayer.prototype = {
// private methods
_animateIcon: function (to, from) {
// define a few things the first time
this._animationProps = {
animStart: null,
from: from,
to: to
};
if (from) {
this.animating = true;
}
else {
this._animationProps.current = this._icons[to].slice();
this.draw();
}
},
_updateAnimations: function (now) {
this._animationProps.animStart = this._animationProps.animStart || now;
var deltaTime = now - this._animationProps.animStart;
var perc = (1 - Math.cos(deltaTime / animTime * pi / 2));
if (deltaTime >= animTime) {
this.animating = false;
perc = 1;
this._animationProps.current = this._icons[this._animationProps.to].slice();
this.draw();
}
else {
var from = this._icons[this._animationProps.from];
var current = [];
for (var i = 0; i < from.length; i++) {
current.push([]);
for (var j = 0; j < from[i].length; j++) {
current[i].push([]);
var to = this._icons[this._animationProps.to][i][j];
current[i][j][0] = from[i][j][0] + (to[0] - from[i][j][0]) * perc;
current[i][j][1] = from[i][j][1] + (to[1] - from[i][j][1]) * perc;
}
}
this._animationProps.current = current;
}
},
_draw: function (progress) {
// common settings
if (isNaN(progress)) {
progress = this.audio.currentTime / this.audio.duration || 0;
}
// clear existing
this._ctx.clearRect(0, 0, this.size, this.size);
// draw bg
this._ctx.beginPath();
this._ctx.arc(this._halfSize, this._halfSize, this._halfSize - (this.borderWidth / 2), 0, doublePi);
this._ctx.closePath();
this._ctx.fillStyle = this.backgroundColor;
this._ctx.fill();
// draw border
// our active path is already the full circle, so just stroke it
this._ctx.lineWidth = this.borderWidth;
this._ctx.strokeStyle = this.borderColor;
this._ctx.stroke();
// play progress
if (progress > 0) {
this._ctx.beginPath();
this._ctx.arc(this._halfSize, this._halfSize, this._halfSize - (this.borderWidth / 2), arcOffset, arcOffset + doublePi * progress);
this._ctx.strokeStyle = this.playedColor;
this._ctx.stroke();
}
// icons
this._ctx.fillStyle = this.iconColor;
if (this.loading) {
var loaderOffset = -Math.cos((new Date().getTime() % (loaderTime)) / (loaderTime) * pi) * doublePi - (pi / 3) - (pi / 2);
this._ctx.beginPath();
this._ctx.arc(this._halfSize, this._halfSize, this._halfSize / 3, loaderOffset, loaderOffset + pi / 3 * 2);
this._ctx.strokeStyle = this.iconColor;
this._ctx.stroke();
}
else {
this._ctx.beginPath();
var icon = (this._animationProps && this._animationProps.current) || this._icons.play;
for (var i = 0; i < icon.length; i++) {
this._ctx.moveTo(icon[i][0][0], icon[i][0][1]);
for (var j = 1; j < icon[i].length; j++) {
this._ctx.lineTo(icon[i][j][0], icon[i][j][1]);
}
}
// this._ctx.closePath();
this._ctx.fill();
// stroke to fill in for retina
this._ctx.strokeStyle = this.iconColor;
this._ctx.lineWidth = 2;
this._ctx.lineJoin = 'miter';
this._ctx.stroke();
}
},
_setState: function (state) {
this.playing = false;
this.loading = false;
if (state === 'playing') {
this.playing = true;
this._animateIcon('pause', 'play');
}
else if (state === 'loading') {
this.loading = true;
}
else if (this.state !== 'loading') {
this._animateIcon('play', 'pause');
}
else {
this._animateIcon('play', null);
}
this.state = state;
this._canvas.setAttribute('class', this.className + ' is-' + state);
this.draw();
},
// public methods
draw: function () {
this._forceDraw = true;
},
setSize: function (size) {
this.size = size;
this._halfSize = size / 2; // we do this a lot. it's not heavy, but why repeat?
this._canvas.width = size;
this._canvas.height = size;
// set icon paths
var iconSize = this.size / 2;
var pauseGap = iconSize / 10;
var playLeft = Math.cos(pi / 3 * 2) * (iconSize / 2) + this._halfSize;
var playRight = iconSize / 2 + this._halfSize;
var playHalf = (playRight - playLeft) / 2 + playLeft;
var top = this._halfSize - Math.sin(pi / 3 * 2) * (iconSize / 2);
var bottom = this.size - top;
var pauseLeft = this._halfSize - iconSize / 3;
var pauseRight = this.size - pauseLeft;
this._icons = {
play: [
[
[playLeft, top],
[playHalf, (this._halfSize - top) / 2 + top],
[playHalf, (this._halfSize - top) / 2 + this._halfSize],
[playLeft, bottom]
],
[
[playHalf, (this._halfSize - top) / 2 + top],
[playRight, this._halfSize],
[playRight, this._halfSize],
[playHalf, (this._halfSize - top) / 2 + this._halfSize]
]
],
pause: [
[
[pauseLeft, top + pauseGap],
[this._halfSize - pauseGap, top + pauseGap],
[this._halfSize - pauseGap, bottom - pauseGap],
[pauseLeft, bottom - pauseGap]
],
[
[this._halfSize + pauseGap, top + pauseGap],
[pauseRight, top + pauseGap],
[pauseRight, bottom - pauseGap],
[this._halfSize + pauseGap, bottom - pauseGap]
]
]
};
if (this._animationProps && this._animationProps.current) {
this._animateIcon(this._animationProps.to);
}
if (!this.playing) {
this.draw();
}
},
setAudio: function (audioUrl) {
this.audio = new Audio(audioUrl);
this._setState('loading');
this.audio.addEventListener('canplaythrough', (function () {
this._setState('paused');
}).bind(this));
this.audio.addEventListener('play', (function () {
this._setState('playing');
}).bind(this));
this.audio.addEventListener('pause', (function () {
// reset when finished
if (this.audio.currentTime === this.audio.duration) {
this.audio.currentTime = 0;
}
this._setState('paused');
}).bind(this));
},
appendTo: function (element) {
element.appendChild(this._canvas);
},
play: function () {
this.audio.play();
},
pause: function () {
this.audio.pause();
}
};
// now init one as an example
var cap = new CircleAudioPlayer({
audio: 'https://www.siriusxm.com/content/dam/sxm-com/audio/test/audio-previews/audio_test03.mp3.png',
size: 120,
borderWidth: 8
});
cap.appendTo(playerContainer);
You can simply use AudioElement.pause() to pause an running element, and the next AudioElement.play() will start from where you left off.
You can essentially set the currentTime property of the audio element to start from the beginning
A simple demonstration of how it works
const pause = document.getElementById('pause');
const stop = document.getElementById('stop');
const play = document.getElementById('play');
const container = document.getElementById('player');
const duration = document.getElementById('duration');
const audio = new Audio('https://www.siriusxm.com/content/dam/sxm-com/audio/test/audio-previews/audio_test03.mp3.png');
let played = 0;
let playing = true;
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
run = async function () {
while(playing) {
if (played == Math.floor(audio.duration)) break;
duration.innerText = `${played} / ${Math.floor(audio.duration)}`;
played++;
await wait(1000);
}
}
container.appendChild(audio);
stop.addEventListener('click', () => {
duration.innerText = `0 / ${Math.floor(audio.duration)}`
audio.pause();
audio.currentTime = 0;
played = 0;
playing = false;
});
pause.addEventListener('click', () => {
audio.pause();
playing = false;
});
play.addEventListener('click', () => {
playing = true
audio.play();
run();
});
<div id="player"></div>
<div id="duration">0.0</div>
<button id="play">play</button>
<button id="stop">stop</button>
<button id="pause">pause</button>

clear interval not stopping at desired point

I looked at some other similar problems on this site and could not fix this problem. Below is part of a pomodoro clock program that I'm making. The problem is that I'm unable to make this set interval method stop when the clock reaches 00:00.
here is my code:
var break_minutes = 0;
var ses_minutes = 0;
var ses_minutes_sec;
var display = document.querySelector('#time');
function increment_ses (id) {
ses_minutes = ses_minutes + 1;
document.getElementById("ses_value").innerHTML = ses_minutes ;
document.getElementById("timmer_circle").innerHTML = ses_minutes;
}
function decrement_ses (id) {
if (ses_minutes > 0) {
ses_minutes = ses_minutes - 10;
} if (ses_minutes < 0) {
ses_minutes = 0;
}
document.getElementById("ses_value").innerHTML = ses_minutes ;
document.getElementById("timmer_circle").innerHTML = ses_minutes;
}
function runTimer () {
var minutes = ses_minutes-1;
var seconds = 10;
var interval = setInterval(function () {
seconds = seconds -1;
if (seconds == 0) {
minutes --;
seconds = 10 -1;
}
function str_pad_left(string,pad,length) {
return (new Array(length+1).join(pad)+string).slice(-length);
}
var finalTime = str_pad_left(minutes,'0',2)+':'+str_pad_left(seconds,'0',2);
document.getElementById("timmer_circle").innerHTML= finalTime;
if (minutes == 0) {
if (seconds == 0) {
return clearInterval(interval);
}
}
},1000);
}
the HTML
<html>
<head>
<title>Pomodoro</title>
<script src="pomodoro.js"></script>
</head>
<body>
<style>
.timmer_circle
{
width: 300px;
height: 300px;
border-radius: 50%;
font-size: 50px;
color: #fff;
line-height: 300px;
text-align: center;
background: #000;
}
.break_length{width:100%;}
#decrement{float:left;width:100px;}
#break_value{text-align: center;padding-left: 100px;}
#increment{margin:0 auto;width:100px;}
.session_length{width:100%; margin-top: 10px;}
#decrement_ses{float:left;width:100px;}
#ses_value{padding-left: 100px;}
#increment_ses{margin:0 auto;width:100px;}
#start_but{margin-top: 20px;}
#pause_but{margin-top: 20px; margin-left: 2px;}
</style>
<table>
<tr>
<td>
<div class = "timmer_circle" id ="timmer_circle" value = ""> <span id = "time">Session</span> </div>
</td>
</tr>
</table>
<div class="session_length">
<button type="button" id = "decrement_ses" onClick = "decrement_ses(this.id);">ses/dec</button>
<button type="button" id = "ses_value" >0</button>
<button type="button" id = "increment_ses" onClick = "increment_ses(this.id);">ses/inc</button>
</div>
<div class="break_length">
<button type="button" id = "decrement" onClick = "decrement_break(this.id);">brk/dec</button>
<button type="button" id = "break_value" value = "" >0</button>
<button type="button" id = "increment" onClick = "increment_break(this.id);">brk/inc</button>
</div>
<button id ="start_but" onClick="runTimer();">START</button>
<button id ="pause_but">PAUSE</button>
</body>
</html>
So, there's a number of issues with your code, specifically how you're calculating seconds and minutes. Seconds are never zero when you hit your case statement the way you're doing it, because you test for zero at the start of your function and then reset them to 10-1.
I would move that check to the start of the function, as part of your initial conditional. There are still other issues, but this is to answer your specific question about the interval. The below code will exit as expected:
var ses_minutes = 1;
var minutes = ses_minutes-1;
var seconds = 10;
var interval = setInterval(function () {
seconds = seconds -1;
if (seconds == 0) {
if(minutes === 0){
return clearInterval(interval);
}
minutes --;
seconds = 10 - 1;
}
function str_pad_left(string,pad,length) {
return (new Array(length+1).join(pad)+string).slice(-length);
}
var finalTime = str_pad_left(minutes,'0',2)+':'+str_pad_left(seconds,'0',2);
document.getElementById("timmer_circle").innerHTML= finalTime;
},1000);
/* EDIT */
So taking a few minutes to think about how I'd do this if it were me, I'd break things up into functions a little differently, and I'd also use setTimeout. I'd also calculate based on elapsed time rather than assuming the interval or timeout tick will happen at exactly 1000ms, since that's not always reliable. The below is probably still not perfect (I've only done cursory testing) but closer to what I'd do if I were tasked with this:
const display = document.getElementById('timer');
const countDownFrom = 15000; // time in milliseconds to count from
let startTime = new Date().getTime();
function padNumber(num){
let str = num.toString();
return str.length > 1 ? str : '0' + str;
}
function getDisplay(milliseconds){
const seconds = milliseconds / 1000;
const displayMinutes = padNumber(Math.floor(seconds / 60));
const displaySeconds = padNumber(Math.floor(seconds % 60));
return displayMinutes + ':' + displaySeconds;
}
function tick(){
const currentTime = new Date().getTime();
const elapsedTime = currentTime - startTime;
// test to see if the timer has expired
if(countDownFrom - elapsedTime <= 0){
display.innerHTML = '00:00';
return;
}
display.innerHTML = getDisplay(countDownFrom - elapsedTime);
setTimeout(tick,1000);
}
display.innerHTML = getDisplay(countDownFrom);
setTimeout(tick, 1000);

How to show minute, second, hour in time progress bar

I have a time progress bar. I use this code. In this time bar, I get the time in seconds, but I want to show minute, second, hour in the time progress bar.
var timer = 0,
timeTotal = 2500,
timeCount = 20,
timeStart = 0,
cFlag;
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text((percentage / 1000).toFixed(2) + "\00a0s");
}
function animateUpdate() {
var perc = new Date().getTime() - timeStart;
if(perc < timeTotal) {
updateProgress(perc);
timer = setTimeout(animateUpdate, timeCount);
} else {
updateProgress(timeTotal);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag == undefined) {
clearTimeout(timer);
cFlag = true;
timeStart = new Date().getTime();
animateUpdate();
}
else if (!cFlag) {
cFlag = true;
animateUpdate();
}
else {
clearTimeout(timer);
cFlag = false;
}
});
});
jsfiddle.net/McNetic/hnfRe/397
You can try this. DEMO LINK HERE
<div id="pbar_outerdiv" style="width: 300px; height: 20px; border: 1px solid grey; z-index: 1; position: relative; border-radius: 5px; -moz-border-radius: 5px;">
<div id="pbar_innerdiv" style="background-color: lightblue; z-index: 2; height: 100%; width: 0%;"></div>
<div id="pbar_innertext" style="z-index: 3; position: absolute; top: 0; left: 0; height: 100%; color: black; font-weight: bold; text-align: center;">0 s</div>
</div>
<p>Click once to start!</p>
<p>Click again to toggle Start/Stop</p>
JS...
var timer = 0,
timeTotal = 250000,
timeCount = 20,
timeStart = 0,
cFlag;
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
var totalSec= (percentage / 1000);
var min = parseInt(totalSec/60);
var sec = parseInt(totalSec%60);
var hr= parseInt(min/60);
min = parseInt(min % 60);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text(hr+":"+min+":"+sec + "");
}
function animateUpdate() {
var perc = new Date().getTime() - timeStart;
if(perc < timeTotal) {
updateProgress(perc);
timer = setTimeout(animateUpdate, timeCount);
} else {
updateProgress(timeTotal);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag == undefined) {
clearTimeout(timer);
cFlag = true;
timeStart = new Date().getTime();
animateUpdate();
}
else if (!cFlag) {
cFlag = true;
animateUpdate();
}
else {
clearTimeout(timer);
cFlag = false;
}
});
});
CSS...
#pbar_outerdiv { cursor: pointer; }
With percentaje (line 11):
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text(x.toFixed(2) + '%');
}
SEE DEMO
With hours, minutes and seconds:
var seconds = 1000;
var minutes = seconds * 60;
var hours = minutes * 60;
var days = hours * 24;
var years = days * 365;
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text( Math.floor(percentage/hours) + 'h ' + Math.floor(percentage/minutes) + 'm ' + Math.floor(percentage/seconds) + 's');
}
SEE DEMO.
I think for that you should use requestAnimationFrame:
var timeTotal = 2500,
timeStart = 0,
cFlag = false;
var seconds = 1000;
var minutes = seconds * 60;
var hours = minutes * 60;
var days = hours * 24;
var years = days * 365;
function updateProgress() {
var time = new Date().getTime() - timeStart;
var x = (time/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text( Math.floor(time/hours) + 'h ' + Math.floor(time/minutes) + 'm ' + Math.floor(time/seconds) + 's');
if(time <= timeTotal && cFlag) {
requestAnimationFrame(updateProgress);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag === false) {
cFlag = true;
timeStart = new Date().getTime();
updateProgress();
}
else {
cFlag = false;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pbar_outerdiv" style="width: 300px; height: 20px; border: 1px solid grey; z-index: 1; position: relative; border-radius: 5px; -moz-border-radius: 5px;">
<div id="pbar_innerdiv" style="background-color: lightblue; z-index: 2; height: 100%; width: 0%;"></div>
<div id="pbar_innertext" style="z-index: 3; position: absolute; top: 0; left: 0; height: 100%; color: black; font-weight: bold; text-align: center;">0h 0m 0s</div>
</div>
<p>Click once to start!</p>
<p>Click again to toggle Start/Stop</p>
UPDATED WITH PAUSE ALLOW AND RESUME:
var timeTotal = 5 * minutes,
timePaused = 0,
timePausedStart = 0,
timeStart = 0,
cFlag = false,
stopped = false;
var seconds = 1000;
var minutes = seconds * 60;
var hours = minutes * 60;
var days = hours * 24;
var years = days * 365;
function updateProgress() {
if( !timePausedStart ) { // if not paused
var time = new Date().getTime() - timeStart - timePaused;
var x = (time/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text( Math.floor(time/hours%24) + 'h ' + Math.floor(time/minutes%60) + 'm ' + Math.floor(time/seconds) + 's');
if(time > timeTotal) {
cFlag = false;
}
if( Math.floor(time/seconds) == 3*60+30 && !stopped){ // pause at 3 m 30 s
stopped = true;
pause();
}
}
if( cFlag )
requestAnimationFrame(updateProgress);
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag === false) {
cFlag = true;
timeStart = new Date().getTime();
timePaused = 0;
updateProgress();
} else if( cFlag === true && timePausedStart ){ // reset pause
timePaused += new Date().getTime() - timePausedStart;
timePausedStart = 0;
}
else {
pause();
}
});
});
var pause = function(){
timePausedStart = new Date().getTime();
};
#pbar_outerdiv { cursor: pointer; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pbar_outerdiv" style="width: 300px; height: 20px; border: 1px solid grey; z-index: 1; position: relative; border-radius: 5px; -moz-border-radius: 5px;">
<div id="pbar_innerdiv" style="background-color: lightblue; z-index: 2; height: 100%; width: 0%;"></div>
<div id="pbar_innertext" style="z-index: 3; position: absolute; top: 0; left: 0; height: 100%; color: black; font-weight: bold; text-align: center;">0h 0m 0s</div>
</div>
<p>Click once to start!</p>
<p>Click again to toggle Start/Stop</p>
Instead of printing (percentage / 1000).toFixed(2), you can use percentage to split your time in millisecond to h:m's.ms
You can simply compute the desired values with integer divisions
h = Math.floor(percentage / 3600000);
m = Math.floor((percentage - h * 3600000) / 60000);
s = Math.floor((percentage - h * 3600000 - m * 60000) / 1000);
ms = Math.floor(percentage - h * 3600000 - m * 60000 - s * 1000);
Then, you can just use toString() to convert your int to strings. I concatenated the values with 0 and and used slice() to keep only the two last character. This allow you to print hours, minutes, ... in two digits format
text = ("0" + h.toString() ).slice(-2) + ":" +
("0" + m.toString() ).slice(-2) + "'" +
("0" + s.toString() ).slice(-2) + "\"" +
("0" + ms.toString()).slice(-2);

How to make my countdown timer go up once it reaches 00:00 using javascript

I was trying to make a countdown timer that once it reaches " 00:00 " it should go up again without limit.
I can't figure it out how to make my countdown go up once it reaches " 00:00 " maybe you can help me.
<html>
<head>
<title>Countdown</title>
<script type="text/javascript">
// set minutes
var mins = 1;
// calculate the seconds (don't change this! unless time progresses at a different speed for you...)
var secs = mins * 60;
var timeout;
function countdown() {
timeout = setTimeout('Decrement()', 1000);
}
function colorchange(minutes, seconds)
{
if(minutes.value =="00" && seconds.value =="59")
{
minutes.style.color="orange";
seconds.style.color="orange";
}
else if(minutes.value =="00" && seconds.value =="30")
{
minutes.style.color="red";
seconds.style.color="red";
}
}
function Decrement() {
if (document.getElementById) {
minutes = document.getElementById("minutes");
seconds = document.getElementById("seconds");
// if less than a minute remaining
if (seconds < 59) {
seconds.value = secs;
} else {
minutes.value = getminutes();
seconds.value = getseconds();
}
colorchange(minutes,seconds);
secs--;
if (secs < 0) {
clearTimeout(timeout);
return;
}
countdown();
}
}
function getminutes() {
// minutes is seconds divided by 60, rounded down
mins = Math.floor(secs / 60);
return ("0" + mins).substr(-2);
}
function getseconds() {
// take mins remaining (as seconds) away from total seconds remaining
return ("0" + (secs - Math.round(mins * 60))).substr(-2);
}
</script>
</head>
<body>
<div id="timer">
This is only valid for the next <input id="minutes" type="text" style="width: 110px; border: none; background-color:none; font-size: 100px; font-weight: bold;"> :
<input id="seconds" type="text" style="width: 110px; border: none; background-color:none; font-size: 100px; font-weight: bold;">
</div>
<script>
countdown();
</script>
I think your current solution is a little overcomplicated. You have a function that sets a timeout that calls another function which does the work and then re-calls the function that sets the timeout again.
Instead of doing that, just use the setInterval method instead.
Similarly to what #JoColina suggested, set a direction variable that indicates which direction to count, and then set up different behavior for counting up vs. counting down.
var direction = 'down';
var mins = 1.1;
var secs = mins * 60;
function colorchange() {
var className;
if (direction == 'up') {
className = 'success';
} else if (secs <= 30) {
className = 'danger';
} else if (secs <= 59) {
className = 'warning';
}
document.getElementById('timeText').className = className;
}
function getminutes() {
// minutes is seconds divided by 60, rounded down
mins = Math.floor(secs / 60);
return ("0" + mins).substr(-2);
}
function getseconds() {
// take mins remaining (as seconds) away from total seconds remaining
return ("0" + (secs - Math.round(mins * 60))).substr(-2);
}
function countdown() {
setInterval(function() {
var minutes = document.getElementById('minutes');
var seconds = document.getElementById('seconds');
minutes.value = getminutes();
seconds.value = getseconds();
colorchange();
if (direction == 'down') {
secs--;
if (secs <= 0) {
direction = 'up';
}
} else if (direction == 'up') {
secs++;
}
}, 1000);
}
countdown();
.success,
.success input {
color: green;
}
.warning,
.warning input {
color: orange;
}
.danger,
.danger input {
color: red;
}
<div id="timer">
This is only valid for the next
<span id="timeText">
<input id="minutes" type="text" style="width: 110px; border: none; background-color:none; font-size: 100px; font-weight: bold;">:
<input id="seconds" type="text" style="width: 110px; border: none; background-color:none; font-size: 100px; font-weight: bold;">
</span>
</div>
tl;dr, however you could declare a global boolean like var down = true;, and once your timer reaches 00:00, you just change down = true to down = false.
Then, on the function that changes the counter you add:
if(down){
Decrement();
}else{
Increment():
}
And if, for example, you want to decrement again once it reaches 13:54 you once more add a down = true.
Hope this helps!

Categories

Resources