JSFiddle - React, Tailwind, and code Playground

by brigand

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<button type="button" class="btn btn-primary">Primary
  <div class="submit-btn">
    <span>Submit</span>

    <svg class="checkmark loader-svg" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
      <path class="check" d="M9 16l5 5 9-9" fill="none" stroke-linecap="round" stroke-dasharray="19.79899024963379" style="stroke-dashoffset: 0px;"></path>
      <circle cx="32" cy="32" r="29" fill="none" stroke="#e6e6e6" stroke-width="6"></circle>
      <circle id="progress" cx="32" cy="32" r="29" fill="none" stroke="#20BF7E" stroke-width="6" stroke-linecap="round" stroke-dasharray="181.91799926757812" style="stroke-dashoffset: 0px;"></circle>
    </svg>
  </div>
</button>

CSS

button {
  position: relative;
  height: 7em;
  width: 7em;
}

.loader-svg {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.check {
  stroke: black;
  stroke-width: 2.5;
}

#progress {
  display: block;
}

.checkmark {
  display: block;
}

JavaScript

const logoTimeline = anime.timeline({ autoplay: false });

logoTimeline
  .add({
    targets: '#progress',
    strokeDashoffset: {
      value: [anime.setDashoffset, 0],
      duration: 1000,
      delay: 200,
      easing: 'easeOutQuart',
    },
  })
  .add({
    targets: '.check',
    strokeDashoffset: {
      value: [anime.setDashoffset, 0],
      duration: 1000,
      delay: 200,
      easing: 'easeOutQuart',
    },
  });

if (document.querySelector('button')) {
  document.querySelector('button').addEventListener('click', () => {
    logoTimeline.play();
  });
}