Need for modification of the javascript countdown code - javascript

Please i have a JavaScript countdown timer code that i got from stackoverflow that is a solution to my countdown timer project. this existing code counts down time from 30minutes down to 1 and start over again. and it gives the same count result to every user at the same time. But my challenge with the code is that i was not able to modify it in other to be able to regulate the count duration, because i want it to countdown from 2minutes to 0 and start over again continually,but not exceeding 2minutes. Please i need someone that will copy this code and run it a see if you can regulate the duration and help me with the solution. thanks in anticipation.
The code is as follows:
setInterval(function() {
function addZero(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
var x = document.getElementById("timer");
var d = new Date();
var s = (d.getSeconds());
var m = (d.getMinutes());
var a = addZero(30 - m);
var b = addZero(60 - m);
var c = (60 - s);
var z = "<span style='color:red;font-size:50px;'>" + "Break" + "</span>";
var v = "<span style='color:black;font-size:24px;'>" + "Break" + "</span>";
if (m > 30) {
y = b;
}
else if (m < 30) {
y = a;
}
if (y < 2 && c < 15) {
q = z;
}
else {
q = v;
}
var t = y + (":" + addZero(c) + " Till Station " + (q));
x.innerHTML = t;
}, 250);
<div align="center" id="timer" style='color:black;font-size:24px;' ></div>

The code you presented deserves a few remarks:
Variable names should be descriptive, not one-letter a, b, c...
Variables should be defined explicitly, not implicitly global, like now happens for y and q
When m is 30, then y does not get a value... this cannot be right.
If that last point would be corrected, then the logic for setting z would pose a new problem.
Styling should be done as much as possible via CSS classes, not via style attribute settings.
Here is how you could do it. You can set the first two constants to your liking:
// Maximum number of seconds for the timer (e.g. 120 = 2 minutes)
const MAX_SECS = 120;
// Number of seconds below which text gets highlighted
const WARN_SECS = 15;
// DOM
const spanMinutes = document.getElementById("min");
const spanSeconds = document.getElementById("sec");
const spanWarning = document.getElementById("break");
// For formatting numbers with 2 digits
const twoDigits = i => i.toString().padStart(2, 0);
setInterval(() => {
let seconds = MAX_SECS - Math.floor(Date.now() / 1000) % MAX_SECS;
spanMinutes.textContent = twoDigits(Math.floor(seconds / 60))
spanSeconds.textContent = twoDigits(seconds % 60);
spanWarning.classList.toggle("warn", seconds < WARN_SECS);
}, 250);
#timer {
text-align: center;
font-size: 24px;
}
.warn {
color: red;
}
<div id="timer"><span id="min">00</span>:<span id="sec">00</span>
till station <span id="break">breaks down</break>
</div>

Related

Why do two seemingly identical JS functions run differently?

I just created a simple JavaScript counter. The first version adds a constant every second to an initial value; the second version adds 1 to the initial value in a proportionately reduced amount of time. I'm not rounding any numbers. But if you let the counter run long enough, the resulting values start diverging considerably. Any idea why that is?
window.onload = function() {
var Today = new Date();
var Jan = new Date("January 1 2020 00:00");
var dif = (Today.getTime() - Jan.getTime()) / 1000;
const Clklid = 3.55988;
var new1 = Clklid * dif;
var new2 = Clklid * dif;
var text = document.getElementById("text")
var text2 = document.getElementById("text2")
setInterval(function() {
new1 += Clklid;
// new1 = Math.trunc(new1);
text.innerHTML = new1 + " g emisí CO2";
}, 1000);
setInterval(function() {
new2 += 1;
// new2 = Math.trunc(new2);
text2.innerHTML = new2 + " g emisí CO2";
}, 1000 / Clklid);
}
<div id="text"></div>
<div id="text2"></div>
https://jsfiddle.net/6t4b1sqk/
setInterval is not perfect and actually takes up to 5 milliseconds longer for each iteration. Intervals that update more often will be behind one that update less.
If you want the 2 timers to always show similar values, only use one counter (replace new1 and new2 with new)
Alternatively, have both counters update in one function and not in the other:
setInterval(function() {
new1 += Clklid;
new2 += 1;
// new1 = Math.trunc(new1);
// new2 = Math.trunc(new2);
text.innerHTML = new1 + " g emisí CO2";
}, 1000);
setInterval(function() {
// new2 = Math.trunc(new2);
text2.innerHTML = new2 + " g emisí CO2";
}, 1000 / Clklid);

Trying to figure out where the variable "now" in this requestAnimationFrame function comes from, or how to obtain its value dynamically

Basically i been trying to create a game using multiple slot machine rollers. I have tried many versions to obtain my goals, and all work perfectly on pc, but as soon as i put them on a mobile device, they are laggy. this is mainly because i was manipulating dom elements, as i found out.
I found a function on the net, i have replicated it and run it in an app and it works perfectly.
Now im trying to write this function into my actual app, with my own variables.
My problem is this:
There is a variable called "NOW", that is passed to the function animate(); I am trying to figure out where it comes from and or how to dynamically create it myself. There is a requestAnimationFrame request in this function and after hours and hours of research, i still cant find anything.
here is a fiddle where the code is located:
https://codepen.io/indamix/pen/lLxcG
var sm = (function(undefined){
var tMax = 3000,
height = 210,
speeds = [],
r = [],
reels = [
['coffee maker', 'teapot', 'espresso machine'],
['coffee filter', 'tea strainer', 'espresso tamper'],
['coffee grounds', 'loose tea', 'ground espresso beans']
],
$reels,
$msg,
start;
function init(){
$reels = $('.reel').each(function(i, el){
el.innerHTML = '<div><p>' + reels[i].join('</p><p>') + '</p></div><div><p>' + reels[i].join('</p><p>') + '</p></div>'
});
$msg = $('.msg');
$('button').click(action);
}
function action(){
if (start !== undefined)
return;
for (var i = 0; i < 3; ++i) {
speeds[i] = Math.random() + .5;
r[i] = (Math.random() * 3 | 0) * height / 3;
}
$msg.html('Spinning...');
animate();
}
function animate(now){
if (!start) start = now;
var t = now - start || 0;
for (var i = 0; i < 3; ++i)
$reels[i].scrollTop = (speeds[i] / tMax / 2 * (tMax - t) * (tMax - t) + r[i]) % height | 0;
if (t < tMax)
requestAnimationFrame(animate);
else {
start = undefined;
check();
}
}
function check(){
$msg.html(
r[0] === r[1] && r[1] === r[2] ?
'You won! Enjoy your ' + reels[1][ (r[0] / 70 + 1) % 3 | 0 ].split(' ')[0] : 'Try again');}
return {init: init}
})();$(sm.init);
I've been at this for a while now, like days. I figured out that the Now variable has something to do with the requestAnimationFrame function to determine where the animation frame ends up,But this is only speculation for me.. I can't see it.
You can use performance.now() as an argument value to your own animate function call

Looping a function, unexpected behaviour

Im wondering what is wrong with this for loop here. I'm trying to make a Pomodoro Study Timer, a study technique that suggests that you break down studying into 25-minute chunks that are followed by 3-5 minute breaks. here I have 2 timers that run in sequence, one after the other. When the first timer reaches zero, the second one starts. For now, i have timers set to 5 seconds and 3 seconds respectively in order to make testing quicker. It all works fine until I put the whole thing into a for loop which then brings some unexpected behaviour. I want to loop the entire function based on user input which informs the code on how many times to loop the counters(this isnt setup yet).
The timers are started by pressing a button on an html page. The button executes the pomo() function at the bottom, which contains a loop that should loop the start() function.
PS, I'm a total ultra noob so apologies if this is just terrible code, I'm really new to this :)
var time25 = 5;
var time5 = 3;
var timeElapsed25 = 0;
var timeElapsed5 = 0; // initializes time elapsed to zero
var time = document.getElementsByClassName("header"); //links to html
time[0].innerHTML = time25; // sets output to html
function convertToMin(s) {
mins = Math.floor(s / 60);
let minsStr = mins.toString();
if (minsStr.length === 1) {
mins = '0' + mins;
}
sec = s % 60;
let secStr = sec.toString();
if (secStr.length === 1) {
sec = '0' + sec;
}
return mins + ':' + sec;
}
function start() {
var timer25 = setInterval(counter25, 1000);
console.log("timer1");
function counter25() {
timeElapsed25++
time[0].innerHTML = convertToMin(time25 - timeElapsed25);
if (timeElapsed25 === time25) {
console.log("timer2")
clearInterval(timer25);
timeElapsed25 = 0;
var timer5 = setInterval(counter5, 1000);
function counter5() { //Counter For 5 minute break
timeElapsed5++;
time[0].innerHTML = convertToMin(time5 - timeElapsed5);
if (timeElapsed5 === time5) {
clearInterval(timer5);
timeElapsed5 = 0;
}
}
}
}
}
function pomo() {
for (j = 0; j < 3; j++) {
start();
}
}
You shouldn't call start() in a loop. setInterval() doesn't wait for the the countdown to complete, it returns immediately, so you're starting all 3 timers at the same time.
What you should do is call start() again when both timers complete. To put a limit on the number of repetitions, use a count parameter, and decrement it each time you call again.
var time25 = 5;
var time5 = 3;
var timeElapsed25 = 0;
var timeElapsed5 = 0; // initializes time elapsed to zero
var time = document.getElementsByClassName("header"); //links to html
time[0].innerHTML = time25; // sets output to html
function pomo() {
start(3);
}
function start(count) {
if (count == 0) { // reached the limit
return;
}
var timer25 = setInterval(counter25, 1000);
console.log("timer1");
function counter25() {
timeElapsed25++
time[0].innerHTML = convertToMin(time25 - timeElapsed25);
if (timeElapsed25 === time25) {
console.log("timer2")
clearInterval(timer25);
timeElapsed25 = 0;
var timer5 = setInterval(counter5, 1000);
function counter5() { //Counter For 5 minute break
timeElapsed5++;
time[0].innerHTML = convertToMin(time5 - timeElapsed5);
if (timeElapsed5 === time5) {
clearInterval(timer5);
timeElapsed5 = 0;
start(count - 1); // Start the next full iteration
}
}
}
}
}
function convertToMin(s) {
mins = Math.floor(s / 60);
let minsStr = mins.toString();
if (minsStr.length === 1) {
mins = '0' + mins;
}
sec = s % 60;
let secStr = sec.toString();
if (secStr.length === 1) {
sec = '0' + sec;
}
return mins + ':' + sec;
}

Javascript Refactoring Assistance Needed

I've programmed this code (javascript countdown) and I have to put 141 of them on page. Doese anybody know if there is some way(program, script etc) that will do the following:
Change from function cdtd1 to function cdtd2 and var sad1 = new Date(); to var sad2 = new Date(); etc.
var d = new Date();
var n = d.getDay();
if(n == 1 || n == 2 || n == 3 || n == 4 || n == 5){
var timer1;
function cdtd1() {
var sad1 = new Date();
var dolazak1 = new Date(sad1.getFullYear(),sad1.getMonth(),sad1.getDate(),23,00,00);
var timeDiff1 = dolazak1.getTime() - sad1.getTime();
if (timeDiff1 <= 0) {
clearInterval(timer1);
$('#dani1Box').remove();
$('#sati1Box').remove();
$('#minute1Box').remove();
$('#sekunde1Box').remove();
}
var sekunde1 = Math.floor(timeDiff1 / 1000);
var minute1 = Math.floor(sekunde1 / 60);
var sati1 = Math.floor(minute1 / 60);
var dani1 = Math.floor(sati1 / 24);
sati1 %= 24;
minute1 %= 60;
sekunde1 %= 60;
$("#dani1Box").html(dani1);
$("#sati1Box").html('7-Dubrava ' + sati1 + ':');
$("#minute1Box").html(minute1 + ':');
$("#sekunde1Box").html(sekunde1);
timer1 = setTimeout(cdtd1, 1000);
}
$(document).ready(function() {
cdtd1();
});
}
I believe what you are looking for is a javscript looping operation.
for(var i = 1; i <= 141; i++) {
console.log(i);
// put code in here that has to run 141 times modifying the html target elements by using string concatenation
$('#target' + i); // This would be come #target1, #target2, #target3 etc up to 141
}
You ask specifically about the variable renaming which would not be necessary in this case since you are reusing the variable in each pass through the loop.
Since you are working with time information you may want to check out this Javascript library: http://momentjs.com/ and work through some of the information on this specific section: http://momentjs.com/docs/#/durations/
JetBrains Webstorm has great javascript refactoring features, including renaming of objects.

Java script count up timer

I have a working count down timer in java script and it count down from 120 seconds to 0, now I want to change it to becomes a COUNT UP timer, try few thing still not work. could anyone help to change it to COUNT UP instead of COUNT DOWN.
Here is the code below:
<script type="text/javascript" >
var m = 0;
var s = 120;
var timer_container = document.getElementById("survey-timer");
timer_container.innerHTML = s + "." + m;
function timer() {
if (m<=0) {
m = 9;
s -= 1;
}
if(s>=0) {
m -= 1;
timer_container.innerHTML = s + "." + m;
setTimeout(timer,100);
}
}
</script>
You want to count up from 120 or from 0.. below one just count up from 0..
<script type="text/javascript" >
var m=0
var s=0
var timer_container=document.getElementById("survey-timer");
timer_container.innerHTML=s+"."+m;
function timer(){
if (m>=9){
m=-1;
s+=1;
}
if(s>=0){
m+=1;
timer_container.innerHTML=s+"."+m;
setTimeout(timer,100);
}
}
</script>
Here is working example from jsfiddle
If it were me, I would do this:
var base = new Date();
var timer_container = document.getElementById("survey-timer");
timer();
function timer() {
var now = new Date();
// elapsed time in seconds
var elapsed = (now - base) / 1000.0;
timer_container.innerHTML = elapsed.toFixed(1);
setTimeout(timer, 100);
}
<div id="survey-timer"> </div>
Because I think the technique used in the question and in rahul's answer might 'slip' if the timeout were delayed for whatever reason.

Categories