Search code examples
javascripthtmlprogress

Changing color of progress bar when it reaches 100%


I have a rounded progress bar that goes for a minute, and starts over. Right now, the background is grey and the progress bar is blue. I need when it reaches 100%, everything is blue, and then when it starts over, the blue stays as a background and the progress bar becomes grey. When it reaches 100%, same thing over again, background is gray and progress bar is blue. Everytime it starts, color changes. Here is my JSFiddle https://jsfiddle.net/BrsJsk/gdLu77dc/

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'></div>
      </div>

{
      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, 600);

      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');
        }
      }
    }

And here is the code for changing colors but its not working.

var barFull = 0;
      if (barFull = 1) {
        progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #c8c9cb');
         quad1.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2'); 
          quad2.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2'); 
          quad3.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
          quad4.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
      }
      else {
        progressbar.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #6edbf2');
         quad1.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #c8c9cb'); 
          quad2.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #c8c9cb'); 
          quad3.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #c8c9cb'); 
          quad4.setAttribute('style', 'box-shadow: inset 0px 0px 0px 50px #c8c9cb');
      }
      if (progress == 100) {
        barFull = 1;
      }  
      else {
        barFull = 0;
      }

Solution

  • I would just modify CSS for progresbar and add one more rule for alternate state:

    div[data-progress] {
      box-sizing: border-box;
      position: relative;
      height: 200px;
      width: 200px;
      background: #c8c9cb;
      color: #6edbf2;
      border-radius: 50%;
      transition: box-shadow 1s;
      overflow: hidden;
    }
    div[data-progress].alternate {
      background: #6edbf2;
      color: #c8c9cb;
    }
    

    Then in JS you need to toggle this .alternate class:

    if (progress === 0) {
        progressbar.classList.toggle('alternate')
        // ...
    }
    

    Check the demo below (I made it progress faster for the demo):

    {
      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, 30);
    
      function incrementProg() {
        progress = parseInt(progressbar.getAttribute('data-progress'));
        progress = (progress + 1) % 100;
    
        if (progress === 0) {
        	progressbar.classList.toggle('alternate')
          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');
        }
    
        /* 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');
        }
    
        /* 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');
        }
    
        /* 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');
        }
      }
    }
    div[data-progress] {
      box-sizing: border-box;
      position: relative;
      height: 200px;
      width: 200px;
      background: #c8c9cb;
      color: #6edbf2;
      border-radius: 50%;
      transition: box-shadow 1s;
      overflow: hidden;
    }
    div[data-progress].alternate {
      background: #6edbf2;
      color: #c8c9cb;
    }
    
    
    .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;
      color: #000;
    }
    
    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'></div>
    </div>

    Few notes. I removed color information for box-shadow from JS and made use of color property for progresbar instead as box-shadow uses color prop as default color if not provided. This allows us to change box-shadow toggling CSS class without polluting JS code.