Battery fill animation

- for welliba

by Ercan Cicek

HTML

<div class="battery-container">
  <div id="level-5" class="level-container" onClick="animateTo(5);">
    <div id="level-5-inner" class="level-inner"></div>
  </div>
  <div id="level-4" class="level-container" onClick="animateTo(4);">
    <div id="level-4-inner" class="level-inner"></div>
  </div>
  <div id="level-3" class="level-container" onClick="animateTo(3);">
    <div id="level-3-inner" class="level-inner"></div>
  </div>
  <div id="level-2" class="level-container" onClick="animateTo(2);">
    <div id="level-2-inner" class="level-inner"></div>
  </div>
  <div id="level-1" class="level-container" onClick="animateTo(1);">
    <div id="level-1-inner" class="level-inner"></div>
  </div>
</div>

SCSS

.battery-container {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
  width: 120px;
  height: 285px;
  border-radius: 8px;
  border: 2px solid #D6D6D6;
  padding: 2px 0;

  >.level-container {
    position: relative;
    width: calc(100% - 8px);
    height: calc(100% / 5 - 4px);
    background-color: #D6D6D6;
    cursor: pointer;

    &#level-5 {
      border-top-left-radius: 4px;
      border-top-right-radius: 4px;
    }

    &#level-1 {
      border-bottom-left-radius: 4px;
      border-bottom-right-radius: 4px;
    }

    >.level-inner {
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      height: 0;
      transition: height 0.1s cubic-bezier(0.47, 0, 0.75, 0.72);
    }
  }
}

JavaScript

var transitionTimeInclDelay = 150,
  activeLevel = 0;

function animateTo(targetLevel) {
  setLevelsBgColor(targetLevel);
  if (targetLevel > activeLevel) {
    for (var currentAnimLevel = 1; currentAnimLevel <= targetLevel; currentAnimLevel++) {
      animateForward(currentAnimLevel, activeLevel);
    }
  } else {
    for (var currentAnimLevel = activeLevel; currentAnimLevel > targetLevel; currentAnimLevel--) {
      animateBackward(currentAnimLevel, activeLevel);
    }
  }
  activeLevel = targetLevel;
}

function setLevelsBgColor(targetLevel) {
  var levelElements = document.getElementsByClassName('level-inner'),
    targetColor = (targetLevel === 5 ? '#2A9D8F' : targetLevel === 4 ? '#6ED8CC' : targetLevel === 3 ? '#E9C46A' : targetLevel === 2 ? '#F4A261' : '#E76F51');
  for (var i = 0; i < levelElements.length; i++) {
    levelElements[i].style.backgroundColor = targetColor;
  }
}

function animateForward(currentAnimLevel) {
  window.setTimeout(function() {
    document.getElementById('level-' + currentAnimLevel + '-inner').style.height = '100%';
  }, transitionTimeInclDelay * (currentAnimLevel - activeLevel - 1));
}

function animateBackward(currentAnimLevel) {
  window.setTimeout(function() {
    document.getElementById('level-' + currentAnimLevel + '-inner').style.height = '0';
  }, transitionTimeInclDelay * (activeLevel - currentAnimLevel));
}