Circular Countdown Timer In JavaScript And CSS3 - MalikDzgn
  • Jelajahi

    Copyright © MalikDzgn -

    mercredi 17 février 2021

    Circular Countdown Timer In JavaScript And CSS3

    Circular Countdown Timer In JavaScript And CSS3

     

    Circular Countdown Timer In JavaScript And CSS3

    Category: Date & Time , Javascript | August 17, 2017
    AUTHOR:Serjobas
    VIEWS TOTAL:25,267 views
    OFFICIAL PAGE:Go to website
    LAST UPDATE:August 17, 2017
    LICENSE:MIT

    Preview:

    Circular Countdown Timer In JavaScript And CSS3

    Description:

    A minimal countdown timer with a SVG based circular countdown indicator, implemented in pure JavaScript and CSS/CSS3.

    How to use it:

    Create the timer settings.

    <div class="setters">
      <div class="minutes-set">
        <button data-setter="minutes-plus">+</button>
        <button data-setter="minutes-minus">-</button>
      </div>
      <div class="seconds-set">
        <button data-setter="seconds-plus">+</button>
        <button data-setter="seconds-minus">-</button>
      </div>
    </div>

    Create the circular countdown indicator.

    <div class="circle">
      <svg width="300" viewBox="0 0 220 220" xmlns="http://www.w3.org/2000/svg">
         <g transform="translate(110,110)">
            <circle r="100" class="e-c-base"/>
            <g transform="rotate(-90)">
               <circle r="100" class="e-c-progress"/>
               <g id="e-pointer">
                  <circle cx="100" cy="0" r="8" class="e-c-pointer"/>
               </g>
            </g>
         </g>
      </svg>
    </div>

    Create the timer controls.

    <div class="controlls">
      <div class="display-remain-time">00:30</div>
      <button class="play" id="pause"></button>
    </div>

    The main CSS styles for the countdown timer.

    button[data-setter] {
      outline: none;
      background: transparent;
      border: none;
      font-family: 'Roboto';
      font-weight: 300;
      font-size: 18px;
      width: 25px;
      height: 30px;
      color: #F7958E;
      cursor: pointer;
    }
    
    button[data-setter]:hover { opacity: 0.5; }
    
    .setters {
      position: absolute;
      left: 85px;
      top: 75px;
    }
    
    .minutes-set {
      float: left;
      margin-right: 28px;
    }
    
    .seconds-set { float: right; }
    
    .controlls {
      position: absolute;
      left: 75px;
      top: 105px;
      text-align: center;
    }
    
    .display-remain-time {
      font-family: 'Roboto';
      font-weight: 100;
      font-size: 65px;
      color: #F7958E;
    }
    
    #pause {
      outline: none;
      background: transparent;
      border: none;
      margin-top: 10px;
      width: 50px;
      height: 50px;
      position: relative;
    }
    
    .play::before {
      display: block;
      content: "";
      position: absolute;
      top: 8px;
      left: 16px;
      border-top: 15px solid transparent;
      border-bottom: 15px solid transparent;
      border-left: 22px solid #F7958E;
    }
    
    .pause::after {
      content: "";
      position: absolute;
      top: 8px;
      left: 12px;
      width: 15px;
      height: 30px;
      background-color: transparent;
      border-radius: 1px;
      border: 5px solid #F7958E;
      border-top: none;
      border-bottom: none;
    }
    
    #pause:hover { opacity: 0.8; }
    
    .e-c-base {
      fill: none;
      stroke: #B6B6B6;
      stroke-width: 4px
    }
    
    .e-c-progress {
      fill: none;
      stroke: #F7958E;
      stroke-width: 4px;
      transition: stroke-dashoffset 0.7s;
    }
    
    .e-c-pointer {
      fill: #FFF;
      stroke: #F7958E;
      stroke-width: 2px;
    }
    
    #e-pointer { transition: transform 0.7s; }

    The main JavaScript to enable the countdown timer.

    //circle start
    let progressBar = document.querySelector('.e-c-progress');
    let indicator = document.getElementById('e-indicator');
    let pointer = document.getElementById('e-pointer');
    let length = Math.PI * 2 * 100;
    
    progressBar.style.strokeDasharray = length;
    
    function update(value, timePercent) {
      var offset = - length - length * value / (timePercent);
      progressBar.style.strokeDashoffset = offset; 
      pointer.style.transform = `rotate(${360 * value / (timePercent)}deg)`; 
    };
    
    //circle ends
    const displayOutput = document.querySelector('.display-remain-time')
    const pauseBtn = document.getElementById('pause');
    const setterBtns = document.querySelectorAll('button[data-setter]');
    
    let intervalTimer;
    let timeLeft;
    let wholeTime = 0.5 * 60; // manage this to set the whole time 
    let isPaused = false;
    let isStarted = false;
    
    
    update(wholeTime,wholeTime); //refreshes progress bar
    displayTimeLeft(wholeTime);
    
    function changeWholeTime(seconds){
      if ((wholeTime + seconds) > 0){
        wholeTime += seconds;
        update(wholeTime,wholeTime);
      }
    }
    
    for (var i = 0; i < setterBtns.length; i++) {
        setterBtns[i].addEventListener("click", function(event) {
            var param = this.dataset.setter;
            switch (param) {
                case 'minutes-plus':
                    changeWholeTime(1 * 60);
                    break;
                case 'minutes-minus':
                    changeWholeTime(-1 * 60);
                    break;
                case 'seconds-plus':
                    changeWholeTime(1);
                    break;
                case 'seconds-minus':
                    changeWholeTime(-1);
                    break;
            }
          displayTimeLeft(wholeTime);
        });
    }
    
    function timer (seconds){ //counts time, takes seconds
      let remainTime = Date.now() + (seconds * 1000);
      displayTimeLeft(seconds);
      
      intervalTimer = setInterval(function(){
        timeLeft = Math.round((remainTime - Date.now()) / 1000);
        if(timeLeft < 0){
          clearInterval(intervalTimer);
          isStarted = false;
          setterBtns.forEach(function(btn){
            btn.disabled = false;
            btn.style.opacity = 1;
          });
          displayTimeLeft(wholeTime);
          pauseBtn.classList.remove('pause');
          pauseBtn.classList.add('play');
          return ;
        }
        displayTimeLeft(timeLeft);
      }, 1000);
    }
    function pauseTimer(event){
      if(isStarted === false){
        timer(wholeTime);
        isStarted = true;
        this.classList.remove('play');
        this.classList.add('pause');
        
        setterBtns.forEach(function(btn){
          btn.disabled = true;
          btn.style.opacity = 0.5;
        });
    
      }else if(isPaused){
        this.classList.remove('play');
        this.classList.add('pause');
        timer(timeLeft);
        isPaused = isPaused ? false : true
      }else{
        this.classList.remove('pause');
        this.classList.add('play');
        clearInterval(intervalTimer);
        isPaused = isPaused ? false : true ;
      }
    }
    
    function displayTimeLeft (timeLeft){ //displays time on the input
      let minutes = Math.floor(timeLeft / 60);
      let seconds = timeLeft % 60;
      let displayString = `${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
      displayOutput.textContent = displayString;
      update(timeLeft, wholeTime);
    }
    
    pauseBtn.addEventListener('click',pauseTimer);

    Share with your friends

    Give us your opinion
    Show Comments
    Close Comment