JSFiddle - React, Tailwind, and code Playground

by Czechler

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.0/CSSRulePlugin.min.js"></script>
    <div class="container">
        <button>
            <span class="label">Submit</span>
            <span class="icon">
                <svg xmlns="http://www.w3.org/2000/svg" width="44.419" height="36.507" viewBox="0 0 44.419 36.507"><defs><style>.a{fill:none;stroke:#fff;stroke-width:2px;}</style></defs><path class="a" d="M130.682,218.058l14.586,17.462,28.295-34.305" transform="translate(-129.915 -200.579)"/></svg>
            </span>
        </button>
    </div>

SCSS

body {
    background: #000;
    margin: 0;
    display: grid;
    place-items: center;
    color: #000;
    font-family: 'Poppins';
    height: 100vh;
}

button {
    background: #AE191E;
    border: none;
    color: white;
    position: relative;
    padding: .5em 1em;
    font-size: 1em;
    font-weight: bold;
    text-align: center;
    border: 2px solid white;
    cursor: pointer;
    border-radius: 24px;
    outline: none;
    width: 10em;
    

    &:before {
      display: none;
        position: absolute;
        content: '';
        background: #5000B8;
        z-index: -1;
        height: 100%;
        width: 100%;
        border-radius: .2em;
        top: .5em;
        left: .5em;
    }
}

svg {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    stroke-dasharray:0 103;
    width: 1.25rem;
    height: auto;
}

p {
    text-align: center;
    font-weight: bold;
    clip-path: circle(0% at 50% 50%);;
}

JavaScript

gsap.registerPlugin(CSSRulePlugin);

        const tl = gsap.timeline({defaults: { ease: Power2.easeOut}})
              btn = document.querySelector('button')
              rule = CSSRulePlugin.getRule("button::before"); //get the rule

        tl.to('.label', {opacity: 0, position: 'absolute', height: 0, duration: '.2s'})
          .to('button', {borderRadius: '50%', width:'2.5em', height: '2.5em', background: '#52b963', ease: Elastic.easeOut.config(.7, 0.3), duration: 1.2}, "-=.5s")
          .to(rule, {borderRadius: '50%'}, "-=1s")
          .to('svg', {strokeDasharray: '90 103'}, "-=.7")
          .from('svg', { opacity: 1}, "-=1s")
          
        
          tl.pause();
        
        btn.addEventListener('click', () => {
            tl.play();
        })