Home > Software engineering >  Progress bar with intervals
Progress bar with intervals

Time:05-10

I am trying to create a progress bar with steps and a play/pause button.

I am having trouble with creating the play/pause button but the case is that onl oad progress bar should not be filling, only after pressing the play button.

The second case I can't figure out is when the progress bar is running if the pause button is pressed it should stop at the end of the interval in which he currently is.

For example, if we press play and the progress bar starts filling up if the pause button is pressed between the starting point and 1st interval, it should stop at the end of the 1st interval, if the pause button is pressed between 1st interval and 2nd interval, it should continue to fill to the end of the 2nd interval etc.

I hope I made it clear.

var value = 0;

function barAnim() {
  value  = 1;
  $(".progress-bar").css("width", value   "%").attr("aria-valuenow", value);
  if (value == 25 || value == 55 || value == 100) {
    $(".progress-bar").append("<p style='position: absolute; text-align: right; width: 25%'>1st interval</p>");
    $(".progress-bar").append("<p style='position: absolute; text-align: right;width: 55%'>2nd interval</p>");
    $(".progress-bar").append("<p style='position: absolute; text-align: right;width: 100%'>3rd interval</p>");
    return setTimeout(barAnim, 500);

  }
  return value >= 100 || setTimeout(barAnim, 20);
}

setTimeout(barAnim, 1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<div  style="width: 500px; position: relative;">
  <div  role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0;background: green;">
    <span >60% Complete</span>
  </div>
</div>
<button onclick="barAnim()">Play</button>

Here is the link to the codepen: https://codepen.io/Wildfactor/pen/WNMwbEP

CodePudding user response:

This is an implementation of a progress bar having some defined checkpoints. After pressing the play button, the button label toggles to "pause" and the progress bar will begin advancing. If the pause button gets clicked, the progress will advance until next checkpoint and stop.

const checkpoints = [25, 55, 100];
const step = 1;
const timeInterval = 100;

//on document ready..
$(document).ready(()=>{
  
  for(checkpoint of checkpoints){
    $('#rulers')
      .append(`<p class='ruler' style='width:${checkpoint}%;'>${checkpoint}</p>`);
  }
        
  //attach click event handler to #playpause button
  $('#playpause').on('click', (event)=>{    
    const status = $(event.currentTarget).attr('data-status');  
    if (status == "pausing"){            
      $(event.currentTarget)
        .attr('data-status', 'playing')
        .text('Pause');    
      setProgressWithCheckpoints(checkpoints, step, timeInterval);
    }else if(status == 'playing'){
      $(event.currentTarget)
        .attr('data-status', 'pausing')
        .text('Play');
    }
  });
});

//set the progressbar at perc
function setProgress(perc){    
  $(".progress .progress-bar")
    .css('width', `${perc}%`)
    .attr('aria-valuenow', perc)
    .text(`${perc}`);    
}

//get progressbar %
function getProgress(){
  const valueNow = $(".progress .progress-bar")
                    .attr('aria-valuenow');
  return parseInt(valueNow);
}

function setProgressWithCheckpoints(intervals, step, ms){
  
  const valueNow = getProgress();     
  const nextIntervals =
    intervals.filter((interval) => interval > valueNow);      
  const nextInterval =
    (nextIntervals.length > 0) ? nextIntervals[0] : null;

  const newValue = Math.min(nextInterval, valueNow step);    
  setProgress(newValue);

  const playpauseStatus = $('#playpause').attr('data-status');

  //if progress got to 100% OR
  //   nextInterval got reached while the play button is in pause state
  if(newValue >= 100 || (nextInterval == newValue && playpauseStatus == 'pausing')){
     //do nothing (this was a cheap way to put the condition in positive terms) 
  }
  //else
  else
    //call again the progress function
    setTimeout(()=>{setProgressWithCheckpoints(intervals, step, ms)}, ms);  
}
.progress{  
  margin: 50px 20px 20px 0;
}

.progress{  
  display: flex;
  width: 100%;  
  height: 2rem;
  overflow: hidden;
  border: solid 1px lightgray;
  width: 100%;
}

.progress-bar{
  color: white;
  vertical-align: middle;
  font-weight: 600;
  padding: 2px 0;
}

#rulers {
  position: relative;
}

#rulers .ruler{
  position: absolute;
  text-align: right;
  margin-top: 0;
}

#playpause {
  display: block;
  cursor: pointer;
  margin-top: 40px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div
    
    role="progressbar"
    aria-valuenow="0"
    aria-valuemin="0"
    aria-valuemax="100"
    style="width: 0%;background: green;">         
  </div>
</div>

<div id="rulers">
</div>

<button id="playpause" data-status="pausing">Play</button>

  • Related