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();
})