Improving my counter
Grant Smith

Grant Smith @granttransition

About: Designer by trade, improving coder 🤪

Location:
Gloucester, UK
Joined:
Oct 2, 2019

Improving my counter

Publish Date: Feb 29 '20
3 5

I've created a count-up clock that I'd like some help refining if you wouldn't mind. Currently, I have two issues that are bugging (pun intended!) me.

  1. The counter doesn't count up the hours, when it reaches two hours, it goes back to 01:01:01
  2. The numbers jump around

Here is my code so far…

// Counter

if (!!document.getElementById("counter")) {
  var minutesLabel = document.getElementById("minutes");
  var secondsLabel = document.getElementById("seconds");
  var totalSeconds = Number(secondsLabel.textContent);
  var totalMinutes = Number(minutesLabel.textContent);

  setInterval(setTime, 1000);

  function setTime() {
   ++totalSeconds;
   secondsLabel.innerHTML = pad(totalSeconds % 60);
   minutesLabel.innerHTML = pad(parseInt(totalMinutes + totalSeconds / 60));
  }

  function pad(val) {
   var valString = val + "";
   if (valString.length < 2) {
    return "0" + valString;
   } else {
    return valString;
   }
  }
 }

// End Counter
#counter {
  background-color: #ee1a25; // TODO: Change this to a pattern
  color: $white;
  text-align: center;

  .counter_wrapper {
    flex-direction: column;

    @include desktop {
      flex-direction: row;
    }
  }

  .counter_container {
    display: flex;
    align-items: center;
    flex-direction: row;
    justify-content: center;

    .counter_number {
      font-weight: regular;
      font-size: 60px;
      font-family: $family-primary;

      font-feature-settings: "tnum";
      font-variant-numeric: tabular-nums;
      @include widescreen {
        font-size: 133px;
      }
    }

    .divider {
      display: inline-block;
      margin: 0 16px;
      width: 8px;
      height: 30px;

      @include widescreen {
        margin: 0 34px;
        width: 16px;
        height: 60px;
      }
    }
  }
}

I'd apprecitate any help and advice offered please

Comments 5 total

  • Grant Smith
    Grant SmithFeb 29, 2020

    This is fantastic, thank you. As for the numbers jumping around, I posted a gif at the top of the post. It is hopefully attached below, although this isn't that important.

    One important thing though (customer request), I need the numbers to start from 01:34:06. Using your method, how would you set the starting numbers?

    New Timer

  • Grant Smith
    Grant SmithFeb 29, 2020

    Yeah, that is exactly what I have done. Page loads with 01:32:20 and then changes the timer to 00:00:20.

    <div class="column is-8 counter_container">
     <span id="hours" class="counter_number">01</span>
     <img class="divider" src="dist/svg/counter-divider.svg" alt="Counter divider" width="16" height="60">
     <span id="minutes" class="counter_number">32</span>
     <img class="divider" src="dist/svg/counter-divider.svg" alt="Counter divider" width="16" height="60">
     <span id="seconds" class="counter_number">20</span>
    </div>
    

    I'll keep working at it, the help is much appreciated, thank you

  • Grant Smith
    Grant SmithMar 1, 2020

    Here is what I worked out; I never actually used the hours or minutes values in the HTML to start with. I was only using the seconds, calculating all the labels with that. The totalSeconds variable should account for the hours and minutes.

    So here is the code I ended up with…

    if (document.getElementById("counter")) {
      const hoursLabel = document.getElementById("hours");
      const minutesLabel = document.getElementById("minutes");
      const secondsLabel = document.getElementById("seconds");
    
        // add all the time values together to give a proper total start point
      let totalSeconds = 
            Number(secondsLabel.textContent)+
            Number(minutesLabel.textContent*60)+
            Number(hoursLabel.textContent*3600);
    
      setInterval(setTime, 1000);
    
      function setTime() {
        ++totalSeconds;
    
          // pull the number of hours out of the total for reference
         const numHours = parseInt(totalSeconds / 3600)
    
         //remove that number fromt he total because it messes up the /60 math if you have extra 3600's in there
         const secondsLeft = parseInt(totalSeconds - 3600 * numHours)
    
         // tweak these for new variables available
        secondsLabel.innerHTML = padWithZero(secondsLeft % 60);
        minutesLabel.innerHTML = padWithZero(parseInt(secondsLeft / 60));
        hoursLabel.innerHTML = padWithZero(numHours);
      }
    
      function padWithZero(num) {
        return Number(num)
          .toString()
          .padStart(2, "0");
      }
    }
    
Add comment