Search code examples
javascripthtmlcssprogress

Progress bar doesn't refresh when it reaches 100


I have a circle progress bar that works, but when it reaches 100% it is supposed to refresh and start over, but it doesn't. Here is my JSFiddle(for some reason it does not work there, but it works on my browser)

https://jsfiddle.net/BrsJsk/5e9hs69y/5/

    window.onload = function() {
  var progressbar = document.querySelector('div[data-progress]'),
    quad1 = document.querySelector('.quad1'),
    quad2 = document.querySelector('.quad2'),
    quad3 = document.querySelector('.quad3'),
    quad4 = document.querySelector('.quad4'),
    counter = document.querySelector('.counter');


  var progInc = setInterval(incrementProg, 1000); // call function every second

  function incrementProg() {
    progress = progressbar.getAttribute('data-progress'); //get current value
    progress++; // increment the progress bar value by 1 with every iteration
    progressbar.setAttribute('data-progress', progress); //set value to attribute
    counter.textContent = 100 - parseInt(progress, 10); // set countdown timer's value
    setPie(progress); // call the paint progress bar function based on progress value
    if (progress == 100) {
      clearInterval(progInc); // clear timer when countdown is complete

    }
  }

  function setPie(progress) {
    /* If progress is less than 25, modify skew angle the first quadrant */
    if (progress <= 25) {
      quad1.setAttribute('style', 'transform: skew(' + progress * (-90 / 25) + 'deg)');
      progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');

    }

    /* Between 25-50, hide 1st quadrant + modify skew angle of 2nd quadrant */
    else if (progress > 25 && progress <= 50) {
      quad1.setAttribute('style', 'transform: skew(-90deg)'); // hides 1st completely
      quad2.setAttribute('style', 'transform: skewY(' + (progress - 25) * (90 / 25) + 'deg)');
      progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
    }

    /* Between 50-75, hide first 2 quadrants + modify skew angle of 3rd quadrant */
    else if (progress > 50 && progress <= 75) {
      quad1.setAttribute('style', 'transform: skew(-90deg)'); // hides 1st completely
      quad2.setAttribute('style', 'transform: skewY(90deg)'); // hides 2nd completely
      quad3.setAttribute('style', 'transform: skew(' + (progress - 50) * (-90 / 25) + 'deg)');
      progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
    }

    /* Similar to above for value between 75-100 */
    else if (progress > 75 && progress < 100) {
      quad1.setAttribute('style', 'transform: skew(-90deg)'); // hides 1st completely
      quad2.setAttribute('style', 'transform: skewY(90deg)'); // hides 2nd completely
      quad3.setAttribute('style', 'transform: skew(-90deg)'); // hides 3rd completely
      quad4.setAttribute('style', 'transform: skewY(' + (progress - 75) * (90 / 25) + 'deg)');
      progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
    }
  }
}
.quad1,
.quad3 {
  transform: skew(0deg);
  /* invisible at -90deg */
}

.quad2,
.quad4 {
  transform: skewY(0deg);
  /* invisible at 90deg */
}


/* Just for demo */

div[data-progress] {
  margin: 40px auto;
}

<div data-progress="0">
  <div class="quad1"></div>
  <div class="quad2"></div>
  <div class="quad3"></div>
  <div class="quad4"></div>
  <div class='counter'>100</div>
</div>

Solution

  • You only stop the interval when reaching 100% progress. To start over, you have to actively reset the progress. You can do so as follows.

    Instead of reading the progress and incrementing it, do this.

    progress = parseInt(progressbar.getAttribute('data-progress'));
    progress = ((progress + 1) % 100);
    

    That is, treat the progress as an integer (because that's what it is) and then wrap the progress around to 0 when reaching 100 using the modulo operator.

    You also have to reset all quadrants of your progress bar.

    if (progress === 0) {
        quad1.setAttribute('style', 'transform: skew(0deg)');
        quad2.setAttribute('style', 'transform: skewY(0deg)');
        quad3.setAttribute('style', 'transform: skew(0deg)');
        quad4.setAttribute('style', 'transform: skewY(0deg)');
    }
    

    This you can insert right after updating the progress. You can get rid of the lines that clear the interval.

    Full demo. I made the interval slightly faster, just for demo purposes.

    var progressbar = document.querySelector('div[data-progress]'),
      quad1 = document.querySelector('.quad1'),
      quad2 = document.querySelector('.quad2'),
      quad3 = document.querySelector('.quad3'),
      quad4 = document.querySelector('.quad4'),
      counter = document.querySelector('.counter');
    
    
    var progInc = setInterval(incrementProg, 50);
    
    function incrementProg() {
      progress = parseInt(progressbar.getAttribute('data-progress'));
      progress = ((progress + 1) % 100);
      if (progress === 0) {
        quad1.setAttribute('style', 'transform: skew(0deg)');
        quad2.setAttribute('style', 'transform: skewY(0deg)');
        quad3.setAttribute('style', 'transform: skew(0deg)');
        quad4.setAttribute('style', 'transform: skewY(0deg)');
      }
      progressbar.setAttribute('data-progress', progress); //set value to attribute
      counter.textContent = 100 - parseInt(progress, 10); // set countdown timer's value
      setPie(progress); // call the paint progress bar function based on progress value
    }
    
    function setPie(progress) {
      /* If progress is less than 25, modify skew angle the first quadrant */
      if (progress <= 25) {
        quad1.setAttribute('style', 'transform: skew(' + progress * (-90 / 25) + 'deg)');
        progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
    
      }
    
      /* Between 25-50, hide 1st quadrant + modify skew angle of 2nd quadrant */
      else if (progress > 25 && progress <= 50) {
        quad1.setAttribute('style', 'transform: skew(-90deg)'); // hides 1st completely
        quad2.setAttribute('style', 'transform: skewY(' + (progress - 25) * (90 / 25) + 'deg)');
        progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
      }
    
      /* Between 50-75, hide first 2 quadrants + modify skew angle of 3rd quadrant */
      else if (progress > 50 && progress <= 75) {
        quad1.setAttribute('style', 'transform: skew(-90deg)'); // hides 1st completely
        quad2.setAttribute('style', 'transform: skewY(90deg)'); // hides 2nd completely
        quad3.setAttribute('style', 'transform: skew(' + (progress - 50) * (-90 / 25) + 'deg)');
        progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
      }
    
      /* Similar to above for value between 75-100 */
      else if (progress > 75 && progress < 100) {
        quad1.setAttribute('style', 'transform: skew(-90deg)'); // hides 1st completely
        quad2.setAttribute('style', 'transform: skewY(90deg)'); // hides 2nd completely
        quad3.setAttribute('style', 'transform: skew(-90deg)'); // hides 3rd completely
        quad4.setAttribute('style', 'transform: skewY(' + (progress - 75) * (90 / 25) + 'deg)');
        progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
      }
    }
    div[data-progress] {
      box-sizing: border-box;
      position: relative;
      height: 200px;
      width: 200px;
      background: #c8c9cb;
      border-radius: 50%;
      transition: all 1s;
      overflow: hidden;
    }
    
    .counter {
      position: absolute;
      height: 100%;
      width: 100%;
      top: 0%;
      left: 0%;
      text-align: center;
      line-height: 200px;
      border-radius: 50%;
      background: transparent;
      z-index: 4;
    }
    
    div>div {
      position: absolute;
      height: 50%;
      width: 50%;
      background: inherit;
      border-radius: 0%;
    }
    
    .quad1,
    .quad2 {
      left: 50%;
      transform-origin: left bottom;
    }
    
    .quad3,
    .quad4 {
      left: 0%;
      transform-origin: right top;
    }
    
    .quad1,
    .quad4 {
      top: 0%;
    }
    
    .quad2,
    .quad3 {
      top: 50%;
    }
    
    .quad1,
    .quad3 {
      transform: skew(0deg);
      /* invisible at -90deg */
    }
    
    .quad2,
    .quad4 {
      transform: skewY(0deg);
      /* invisible at 90deg */
    }
    
    
    /* Just for demo */
    
    div[data-progress] {
      margin: 40px auto;
    }
    <div data-progress="0">
      <div class="quad1"></div>
      <div class="quad2"></div>
      <div class="quad3"></div>
      <div class="quad4"></div>
      <div class='counter'>100</div>
    </div>