bubbles pop animation

- for welliba

by Ercan Cicek

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.7.13/lottie.min.js"></script>
<div id="anim-wrapper">
  <div id="anim-container">
    <div id="anim"></div>
  </div>
  <svg class="progress-ring" width="104" height="104">
    <circle class="progress-ring__circle" stroke="#2A9D8F" stroke-width="8" stroke-linecap="round" fill="transparent" r="52" cx="52" cy="52" />
  </svg>
</div>
<input
  value="5"
  type="number"
  step="5"
  min="5"
  max="95"
  placeholder="progress"
>
<button onClick="startAnimation()">start anim</button>

SCSS

html,body {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 40px;
  background-color: #FAF8FF;
  #anim-wrapper {
    position: relative;
    width: 104px;
    height: 104px;
    overflow: visible;
    > svg {
      position: absolute;
      left: 0;
      top: 0;
      overflow: visible;
      > .progress-ring__circle {
        transition: stroke-dashoffset 0.35s;
        transform: rotate(-90deg);
        transform-origin: 50% 50%;
      }
    }
    > #anim-container {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 122px;
      height: 122px;
      transform: translate(-50%, -50%);
      > #anim {
        width: 20px;
        margin: 0 auto;
      }
    }
  }
}

JavaScript

var circle = document.querySelector('circle'),
  radius = circle.r.baseVal.value,
  circumference = radius * 2 * Math.PI;
circle.style.strokeDasharray = `${circumference} ${circumference}`;
circle.style.strokeDashoffset = `${circumference}`;

const inputElem = document.querySelector('input'),
  animContElem = document.getElementById("anim-container");

setTimeout(function() {
  initAnimation();
  startAnimation();
}, 10);

function initAnimation() {
  stopAndHideAnimation();
  lottie.loadAnimation({
    container: document.getElementById('anim'),
    loop: false,
    autoplay: false,
    animationData: JSON.parse(animData)
  });
}

function startAnimation() {
  stopAndHideAnimation();
  animContElem.style.transform = "translate(-50%, -50%) rotate(" + (360 / (100 / inputElem.value)) + "deg)";
  setProgress(inputElem.value);
  setTimeout(function() {
    animContElem.style.visibility = "visible";
    lottie.play();
  }, 250);
}

function stopAndHideAnimation() {
  animContElem.style.visibility = "hidden";
  lottie.stop();
}

function setProgress(percent) {
  if (percent <= 100 && percent >= 0) {
    const offset = circumference - percent / 100 * circumference;
    circle.style.strokeDashoffset = offset;
  }
}

var animData = '{"v":"5.7.4","fr":60,"ip":0,"op":60,"w":360,"h":320,"nm":"Komp 5","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"wave","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[180,160,0],"ix":2,"l":2},"a":{"a":0,"k":[-45.734,20.651,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[35,35]},{"t":16,"s":[290,290]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape -...