Tofu
Tofu

Reputation: 3613

Count down timer with increment

I have a switch and a timer. The switch just changes values between 0 and 1 and the timer is an interval every 5 seconds. When the interval is hit, the switch value changes (if it was 0 now it's 1, if it was 1 now it's 0) and I also have a button which forces the switch value to change and resets the timer.

I also have another timer which is running at 5ms interval and that's just to display how much time is left on the 5 second interval.

Now this is where I'm stuck. I have a button which is supposed to increment that time left by two seconds. So if three seconds have passed since the last switch, and I hit increment, now we're at six seconds until the next switch.. And that part has just been confusing me on how I should go about doing it.

Here's my html and javascript code

window.addEventListener('DOMContentLoaded', (event) => {
    let timer = document.getElementById("timer");
    let switchvalue = document.getElementById("switchvalue");
    let force = document.getElementById("force");
    let increment = document.getElementById("increment");
    let boolvalue = false;
    let maxtime = 5000;
    var tick = Date.now();
    var switchinterval = setInterval(timecounter,maxtime);

    function update(){
        tick = Date.now();
        boolvalue = !boolvalue;
        switchvalue.textContent = boolvalue;
        
        clearInterval(switchinterval);
        switchinterval = setInterval(timecounter,maxtime);

    }

    function timecounter(){
        update();
    }

    let displayinterval = setInterval(() => {
        let now = Date.now();
        let elapsed = now-tick;
        timer.textContent = maxtime-elapsed;
    }, 5);
    force.addEventListener("click",e=>{
        update();
    });

increment.addEventListener("click",e=>{
    //What do I do here?
});
});
<html>
    <head>
        <script src="timer.js"></script>
    </head>
    <body>
        <div id="timer">10</div>
        <div id="switchvalue">false</div>
        <button id="force">Switch</button>
        <button id="increment">Increment</button>
    </body>
</html>

I'm not sure how to make that increment button function. It seems like a simple enough problem to solve..but my brains not working

Upvotes: 1

Views: 511

Answers (1)

Mister Jojo
Mister Jojo

Reputation: 22320

If I understood your question correctly, your increment button should simply add two seconds, right?

increment.onclick =e=>
  {
  tick += 2000  // add 2s
  }

const timer       = document.getElementById("timer") 
  ,   switchvalue = document.getElementById("switchvalue")
  ,   force       = document.getElementById("force")
  ,   increment   = document.getElementById("increment")
  ;
let boolvalue = false
  , maxtime   = 5000
  , tick      = Date.now()
  , switchinterval
  , displayinterval
  ;
switchinterval = setInterval(timecounter, maxtime)
  ;
function update() 
  {
  tick = Date.now()
  boolvalue = !boolvalue
  switchvalue.textContent = boolvalue
  clearInterval(switchinterval)
  switchinterval = setInterval(timecounter, maxtime)
  }
function timecounter()
  {
  update()
  }
displayinterval = setInterval(_=>
  {
  let now     = Date.now()
    , elapsed = now - tick 
  timer.textContent = maxtime - elapsed
  }, 5)

force.onclick =e=>
  {
  update()
  }
increment.onclick =e=>
  {
  tick += 2000  // add 2s
  }
<div id="timer">?</div>
<div id="switchvalue">false</div>
<button id="force">Switch</button>
<button id="increment">Increment</button>

But you forgot to take into account that the delay indicated in setInterval is not reliable, it represents just a hypothetical delay according to the availability of the system, most often (always) it is late.

If you want to have a reliable delay, you must use the value of the system clock to check the elapsed delay.

Which is precisely the case study of your exercise, and which has the merit of using only one setInterval to do everything:

const timer       = document.getElementById("timer") 
  ,   switchvalue = document.getElementById("switchvalue")
  ,   force       = document.getElementById("force")
  ,   increment   = document.getElementById("increment")
  ;
let boolvalue  = false
  , maxtime    = 5000
  , timeTarget = Date.now() + maxtime
  , interval_5ms
  ;
const timeSwich =_=>
  {
  switchvalue.textContent = boolvalue = !boolvalue
  timeTarget = Date.now() + maxtime    
  }
interval_5ms = setInterval(_=>
  {
  let tim = timeTarget - Date.now()
  if ( tim<=0 )
    {
    timeSwich()
    tim = maxtime
    }
  timer.textContent = tim
  }, 5)

force.onclick = timeSwich

increment.onclick =_=>
  {
  timeTarget = Math.min((timeTarget +2000), Date.now() + maxtime)
  // timeTarget += 2000  // add 2s
  }
<div id="timer">?</div>
<div id="switchvalue">false</div>
<button id="force">Switch</button>
<button id="increment">Increment</button>

Upvotes: 2

Related Questions