JSFiddle - React, Tailwind, and code Playground

by rexonms

HTML

<div class="enough-energy">
  <p>You have enough energy to continue your trip.</p>
</div>
<div class="wrapper">
  <div class="charge-stage"></div>
</div>
<div class="timer">
  <span class="hour">0</span> <span class="label">hour  </span><span class="minute">0</span><span class="label">minutes</span>
</div>

CSS

.enough-energy {
  opacity: 0;
}
.wrapper {
  border: 1px solid #ccc;
  height: 50px;
  width: 300px;
  margin: 20px 0;
  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIxcHgiIGhlaWdodD0iMXB4IiB2aWV3Qm94PSIwIDAgMSAxIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPiAgICAgICAgPHRpdGxlPlJlY3RhbmdsZTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz48L2RlZnM+ICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZSIgZmlsbD0iI0NDQ0NDQyIgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSI+PC9yZWN0PiAgICA8L2c+PC9zdmc+);
    background-position:80%;
    background-position-y: initial;
    background-repeat-x: no-repeat;
}

.charge-stage{
  width: 0%;
  height: 100%;
  background: #23b900;
}

.timer span {
  font-size: 28px;
}

.timer span.label {
  font-size: 18px;
  color: #999;
}

JavaScript

let batteriesTimeToChargeMap  = {
	"90D" : [
  	{ minute: 0, percentage: 0 },
    { minute: 2, percentage: 5 },
    { minute: 4, percentage: 10 },
    { minute: 6, percentage: 15 },
    { minute: 8, percentage: 20 },
    { minute: 10, percentage: 25 },
    { minute: 13, percentage: 30 },
    { minute: 15, percentage: 35 },
    { minute: 18, percentage: 40 },
    { minute: 20, percentage: 45 },
    { minute: 23, percentage: 50 },
    { minute: 27, percentage: 55 },
    { minute: 30, percentage: 60 },
    { minute: 34, percentage: 65 },
    { minute: 39, percentage: 70 },
    { minute: 44, percentage: 75 },
    { minute: 50, percentage: 80 },
    { minute: 57, percentage: 85 },
    { minute: 65, percentage: 90 },
    { minute: 74, percentage: 95 },
    { minute: 89, percentage: 100 }
  ]
}

let intervalTime = 10
let chargeTracker = 0
let friction = 10 // higher the number slower speed

animate(batteriesTimeToChargeMap["90D"])

function animate(battery) {
  let maxTime = battery[chargeTracker+1]['minute'] - battery[chargeTracker]['minute']
  let maxPercentage =  battery[chargeTracker+1]['percentage'] - battery[chargeTracker]['percentage']
  window.width = battery[chargeTracker].percentage
	window.percentageIncreament = (maxPercentage/maxTime)/friction
  if (battery[chargeTracker]['percentage'] >= 80) {
  	document.querySelector('.enough-energy').style.opacity = `1`    
  }

  chargeTracker++
	window.animation = setInterval(updateWidth.bind(null, battery[chargeTracker]['percentage'], battery, chargeTracker), intervalTime)
 
}

function updateWidth(maxPercentage, battery, chargeTracker) {
console.log('triggered')
		width += percentageIncreament
    if(width <= maxPercentage) {
			return document.querySelector('.charge-stage').style.width = `${width}%`    
    }
    clearInterval(animation)
    if (chargeTracker < battery.length-1) {
    	animate(battery)
    }
}