Progressbar

by Stalk

HTML

<div id="progressbar"></div>

<input type="button" onclick="p.run()" value="run">
<input type="button" onclick="p.stop()" value="stop">
<input type="button" onclick="p.pause()" value="pause">
<input type="button" onclick="p.reset()" value="reset">
<input type="button" onclick="p.complete()" value="complete">
<hr>
<input type="button" onclick="p.run(400)" value="delay 400">
<input type="button" onclick="p.run(100)" value="delay 100">
<input type="button" onclick="p.set(30)" value="set 30%">
<input type="button" onclick="p.set(70)" value="set 70%">

CSS

#progressbar {
  display: flex;
  align-items: center;
  height: 2em;
  width: 100%;
  min-width: 4em;
  border: solid 2px lightgray;
  position: relative;
}
#progressbar > div {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0;
  background: linear-gradient(to top, #090, #0a0, #0c0, #0a0);
  transition: width .3s ease;
  z-index: -1;
}
#progressbar:after {
  content: attr(data-progress) '%';
  display: block;
  margin: auto;
}

JavaScript

console.clear()
function progressBar(selector){
  this.delay = 500
  this.step = 1
  this.run = function(delay){
    p.delay = delay || p.delay
    if(timer) p.stop()
    timer = setInterval(go, p.delay)
    return p
  }
  this.stop = function(){
    clearInterval(timer)
    timer = false
    return p
  }
  this.reset = function(){
    p.stop().set(0)
    return p
  }
  this.set = function(val){
    val = parseInt(val)
    if (val >= 100) {
      val = 100
      p.stop().oncomplete()
    }
    p.progressbar.setAttribute('data-progress', val)
    p.filler.style.width = val + '%'
    return p
  }
  this.complete = function(){
    go(101)
    return p
  }
  this.pause = function(){
    if(timer) {
      p.stop()
    } else {
      p.run()
    }
    return p
  }
  this.oncomplete = function(){}
  var p = this,
      timer = false,
      go = function(val){ p.set(val || getProgress() + p.step) },
      getProgress = function(){
        return parseInt(p.progressbar.getAttribute('data-progress')) || 0
      }
  this.progressbar = document.querySelector(selector)
  this.filler = document.createElement('div')
  this.progressbar.appendChild(p.filler)
  return this
}

p = new progressBar('#progressbar')
p.run(500)