Search code examples
javascripthtmljquerycsscountdown

24h countdown timer with progress bar


I am working on an application to help people create new habits or discard old ones. For this application, I want to have a countdown timer which counts down every day, thanks to this post I got this to work, the next step is to add a progress bar which counts down along with the timer (so basically 00:00 = full progress bar, 23:59 = empty progress bar).

I have been looking everywhere but I can't seem to figure it out or even get a start with it. I would like to see #goal-time decreasing.

I hope someone could give me some directions/hints or even some snippets if that's possible! Thanks!

(function() {
  var start = new Date;
  start.setHours(24, 0, 0); //hh:mm:ss

  function pad(num) {
    return ("0" + parseInt(num)).substr(-2);
  }

  function tick() {
    var now = new Date;
    if (now > start) { // too late, go to tomorrow
      start.setDate(start.getDate() + 1);
    }
    var remain = ((start - now) / 1000);
    var hh = pad((remain / 60 / 60) % 60);
    var mm = pad((remain / 60) % 60);
    var ss = pad(remain % 60);
    document.getElementById('time').innerHTML = hh + ":" + mm + ":" + ss;
    setTimeout(tick, 1000);
  }

  document.addEventListener('DOMContentLoaded', tick);
})();
.goal-progress {
  border-color: black;
  border-style: solid;
  border-width: thick;
  height: 80px;
  margin-top: 50px;
  margin-left: 20px;
  margin-right: 20px;
  background-color: black;
}

#time {
  float: right;
  line-height: 80px;
  margin-right: 20px;
  background-color: black;
  color: white;
  mix-blend-mode: difference;
}

.goal-time-container {
  height: 80px;
  background-color: white;
  margin-left: 115px;
}

#goal-time {
  background-color: black;
  height: 80px;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="goal-progress">
  <div id="time"></div>
  <!-- time countdown -->
  <div id="img"></div>
  <div class="goal-time-container">
    <!-- container of the progress bar -->
    <div id="goal-time"></div>
    <!-- soon to (hopefully) be progress bar -->
  </div>
</div>


Solution

  • To achieve this you can take the seconds held in the remain variable and use them to work out the percentage of the seconds remaining in one day, 86400, and then set that percentage as the width of the progress bar:

    (function() {
      var start = new Date;
      start.setHours(24, 0, 0); //hh:mm:ss
    
      function pad(num) {
        return ("0" + parseInt(num)).substr(-2);
      }
    
      function tick() {
        var now = new Date;
        if (now > start) { // too late, go to tomorrow
          start.setDate(start.getDate() + 1);
        }
        var remain = ((start - now) / 1000);
        var hh = pad((remain / 60 / 60) % 60);
        var mm = pad((remain / 60) % 60);
        var ss = pad(remain % 60);
        document.getElementById('time').innerHTML = hh + ":" + mm + ":" + ss;
        
        // bar width calulation:
        var pc = remain * (100 / 86400);
        document.querySelector('#goal-time').style.width = pc + '%';
        
        setTimeout(tick, 1000);
      }
    
      document.addEventListener('DOMContentLoaded', tick);
    })();
    .goal-progress {
      border: 5px solid #000;
      height: 80px;
      margin: 50px 20px 20px 0;
      background-color: black;
    }
    
    #time {
      float: right;
      line-height: 80px;
      margin-right: 20px;
      background-color: black;
      color: white;
      mix-blend-mode: difference;
    }
    
    .goal-time-container {
      height: 80px;
      background-color: white;
      margin-left: 115px;
    }
    
    #goal-time {
      background-color: black;
      height: 80px;
      width: 100%;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="goal-progress">
      <div id="time"></div>
      <div id="img"></div>
      <div class="goal-time-container">
        <div id="goal-time"></div>
      </div>
    </div>