<button class="button">
    <svg class="circle" viewBox="0 0 76 76">
        <circle class="default" cx="38" cy="38" r="36"></circle>
        <circle class="active" cx="38" cy="38" r="36"></circle>
    </svg>
    <div class="icon">
        <svg class="line" viewBox="0 0 4 37">
            <line x1="2" y1="2" x2="2" y2="35"></line>
        </svg>
        <div>
            <svg class="arrow" viewBox="0 0 40 32"></svg>
            <svg class="progress" viewBox="0 0 444 10">
                <path d="M2,5 L42,5 C60.0089086,6.33131695 73.3422419,6.99798362 82,7 C87.572404,7.00129781 91.0932494,1.72677301 102,1.99944178 C112.906751,2.27211054 112.000464,7.99986045 122,8 C131.999536,8.00013955 132,2 142,2 C152,2 152,8 162,8 C172,8 172,2 182,2 C192,2 192,8 202,8 C212,8 212,2 222,2 C232,2 232,8 242,8 C252,8 252,2 262,2 C272,2 272,8 282,8 C292,8 292,2 302,2 C312,2 312,8 322,8 C332,8 332,2 342,2 C352,2 351.897852,7.49489262 362,8 C372.102148,8.50510738 378.620177,5.22532154 402,5 L442,5"></path>
            </svg>
        </div>
    </div>
    <span>0%</span>
</button>

<!-- twitter / dribbble -->
<a class="dribbble" href="https://dribbble.com/shots/9683055-Download-animation" target="_blank"><img src="https://dribbble.com/assets/logo-small-2x-9fe74d2ad7b25fba0f50168523c15fda4c35534f9ea0b1011179275383035439.png" alt=""></a>
<a class="twitter" target="_top" href="https://twitter.com/aaroniker_me"><svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72"><path d="M67.812 16.141a26.246 26.246 0 0 1-7.519 2.06 13.134 13.134 0 0 0 5.756-7.244 26.127 26.127 0 0 1-8.313 3.176A13.075 13.075 0 0 0 48.182 10c-7.229 0-13.092 5.861-13.092 13.093 0 1.026.118 2.021.338 2.981-10.885-.548-20.528-5.757-26.987-13.679a13.048 13.048 0 0 0-1.771 6.581c0 4.542 2.312 8.551 5.824 10.898a13.048 13.048 0 0 1-5.93-1.638c-.002.055-.002.11-.002.162 0 6.345 4.513 11.638 10.504 12.84a13.177 13.177 0 0 1-3.449.457c-.846 0-1.667-.078-2.465-.231 1.667 5.2 6.499 8.986 12.23 9.09a26.276 26.276 0 0 1-16.26 5.606A26.21 26.21 0 0 1 4 55.976a37.036 37.036 0 0 0 20.067 5.882c24.083 0 37.251-19.949 37.251-37.249 0-.566-.014-1.134-.039-1.694a26.597 26.597 0 0 0 6.533-6.774z"></path></svg></a>
.button {
    --default: rgba(255, 255, 255, .2);
    --active: #fff;
    position: relative;
    border: none;
    outline: none;
    background: none;
    padding: 0;
    -webkit-appearance: none;
    -webkit-tap-highlight-color: transparent;
    cursor: pointer;
    transform: scale(var(--s, 1));
    transition: transform .2s;
    &:active {
        --s: .96;
    }
    svg {
        display: block;
        fill: none;
        stroke-width: var(--sw, 3px);
        stroke-linecap: round;
        stroke-linejoin: round;
    }
    .circle {
        width: 76px;
        height: 76px;
        transform: rotate(-90deg);
        circle {
            &.default {
                stroke: var(--default);
            }
            &.active {
                stroke: var(--active);
                stroke-dasharray: 227px;
                stroke-dashoffset: var(--active-offset, 227px);
                transition: stroke-dashoffset var(--all-transition, 4s) ease var(--all-delay, .8s);
            }
        }
    }
    span {
        display: block;
        position: absolute;
        left: 0;
        right: 0;
        text-align: center;
        bottom: 13px;
        font-weight: 500;
        font-size: 10px;
        color: var(--active);
        opacity: var(--count-opacity, 0);
        transform: translateY(var(--count-y, 4px));
        animation: var(--count, none) .3s ease forwards var(--all-delay, 4.6s);
        transition: opacity .2s ease .6s, transform .3s ease .6s;
    }
    .icon {
        --sw: 2px;
        width: 24px;
        height: 40px;
        position: absolute;
        left: 50%;
        top: 50%;
        margin: -20px 0 0 -12px;
        svg {
            &.line {
                width: 4px;
                height: 37px;
                stroke: var(--active);
                position: absolute;
                left: 10px;
                top: 0;
                stroke-dasharray: 0 33px var(--line-array, 33px) 66px;
                stroke-dashoffset: var(--line-offset, 33px);
                transform: translateY(var(--line-y, 0));
                opacity: var(--line-opacity, 1);
                transition: stroke-dasharray .2s, stroke-dashoffset .2s, transform .32s ease var(--all-delay, .25s);
            }
        }
        div {
            width: 40px;
            height: 32px;
            position: absolute;
            overflow: hidden;
            left: 50%;
            bottom: 1px;
            margin-left: -20px;
            transform: translate(var(--icon-x, 0), var(--icon-y, 0));
            transition: transform .3s ease var(--all-delay, 4.8s);
            animation: var(--overflow, none) 0s linear forwards var(--all-delay, 4.8s);
            &:before,
            &:after {
                content: '';
                position: absolute;
                z-index: 1;
                height: 2px;
                left: var(--l, 0);
                top: 15px;
                width: var(--w, 16px);
                background: var(--active);
                border-radius: 1px;
                transform-origin: var(--tx, 15px) 1px;
                transform: rotate(var(--before-rotate, 0deg));
                opacity: var(--tick-opacity, 0);
                transition: transform .4s ease var(--all-delay, 4.8s), opacity 0s linear var(--all-delay, 4.8s);
            }
            &:after {
                --l: 14px;
                --w: 26px;
                --tx: 1px;
                transform: rotate(var(--after-rotate, 0deg));
            }
            svg {
                stroke: var(--active);
                &.arrow {
                    width: 40px;
                    height: 32px;
                    opacity: var(--arrow-opacity, 1);
                    transition: opacity 0s linear var(--all-delay, 1s);
                }
                &.progress {
                    width: 444px;
                    height: 10px;
                    position: absolute;
                    left: 0;
                    top: 11px;
                    transform: translateX(var(--progress-x, 0));
                    opacity: var(--progress-opacity, 0);
                    transition: transform var(--all-transition, 4.4s) ease var(--all-delay, .4s), opacity 0s linear var(--all-delay, 1s);
                    animation: var(--hide, none) 0s linear forwards var(--all-delay, 4.8s);
                }
            }
        }
    }
    &.loading:not(.reset) {
        --line-y: -36px;
        --line-array: 0;
        --line-offset: 15px;
        --active-offset: 0;
        --arrow-opacity: 0;
        --progress-opacity: 1;
        --progress-x: -400px;
        --tick-opacity: 1;
        --before-rotate: 47deg;
        --after-rotate: -46deg;
        --hide: hide;
        --overflow: overflow;
        --icon-x: 2px;
        --icon-y: 7px;
        --count-opacity: 1;
        --count-y: 0;
        --count: count;
    }
    &.reset {
        --all-delay: 0s;
        --all-transition: .3s;
    }
}

@keyframes hide {
    to {
        opacity: 0;
    }
}

@keyframes count {
    to {
        transform: translateY(4px);
        opacity: 0;
    }
}

@keyframes overflow {
    to {
        overflow: visible;
    }
}

html {
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
}

* {
    box-sizing: inherit;
    &:before,
    &:after {
        box-sizing: inherit;
    }
}

// dribbble & twitter
body {
    min-height: 100vh;
    font-family: 'Inter', 'Inter UI', Arial;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #275EFE;
    font-family: 'Roboto', Arial, sans-serif;
    .dribbble {
        position: fixed;
        display: block;
        right: 20px;
        bottom: 20px;
        img {
            display: block;
            width: 76px;
        }
    }
    .twitter {
        position: fixed;
        display: block;
        right: 112px;
        bottom: 14px;
        svg {
            width: 24px;
            height: 24px;
            fill: white;
        }
    }
}
View Compiled
const $ = (s, o = document) => o.querySelector(s);
const $$ = (s, o = document) => o.querySelectorAll(s);

$$('.button').forEach(button => {

    let count = {
            number: 0
        },
        icon = $('.icon', button),
        iconDiv = $('.icon > div', button),
        arrow = $('.icon .arrow', button),
        countElem = $('span', button),
        svgPath = new Proxy({
            y: null,
            s: null,
            f: null,
            l: null
        }, {
            set(target, key, value) {
                target[key] = value;
                if(target.y !== null && target.s != null && target.f != null && target.l != null) {
                    arrow.innerHTML = getPath(target.y, target.f, target.l, target.s, null);
                }
                return true;
            },
            get(target, key) {
                return target[key];
            }
        });

    svgPath.y = 30;
    svgPath.s = 0;
    svgPath.f = 8;
    svgPath.l = 32;

    button.addEventListener('click', e => {
        if(!button.classList.contains('loading')) {

            if(!button.classList.contains('animation')) {

                button.classList.add('loading', 'animation');

                gsap.to(svgPath, {
                    f: 2,
                    l: 38,
                    duration: .3,
                    delay: .15
                });

                gsap.to(svgPath, {
                    s: .2,
                    y: 16,
                    duration: .8,
                    delay: .15,
                    ease: Elastic.easeOut.config(1, .4)
                });

                gsap.to(count, {
                    number: '100',
                    duration: 3.8,
                    delay: .8,
                    onUpdate() {
                        countElem.innerHTML = Math.round(count.number) + '%';
                    }
                });

                setTimeout(() => {
                    iconDiv.style.setProperty('overflow', 'visible');
                    setTimeout(() => {
                        button.classList.remove('animation');
                    }, 600);
                }, 4820);

            }

        } else {

            if(!button.classList.contains('animation')) {

                button.classList.add('reset');

                gsap.to(svgPath, {
                    f: 8,
                    l: 32,
                    duration: .4
                });

                gsap.to(svgPath, {
                    s: 0,
                    y: 30,
                    duration: .4
                });

                setTimeout(() => {
                    button.classList.remove('loading', 'reset');
                    iconDiv.removeAttribute('style');
                }, 400);

            }

        }
        e.preventDefault();
    });

});

function getPoint(point, i, a, smoothing) {
    let cp = (current, previous, next, reverse) => {
            let p = previous || current,
                n = next || current,
                o = {
                    length: Math.sqrt(Math.pow(n[0] - p[0], 2) + Math.pow(n[1] - p[1], 2)),
                    angle: Math.atan2(n[1] - p[1], n[0] - p[0])
                },
                angle = o.angle + (reverse ? Math.PI : 0),
                length = o.length * smoothing;
            return [current[0] + Math.cos(angle) * length, current[1] + Math.sin(angle) * length];
        },
        cps = cp(a[i - 1], a[i - 2], point, false),
        cpe = cp(point, a[i - 1], a[i + 1], true);
    return `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${point[0]},${point[1]}`;
}

function getPath(update, first, last, smoothing, pointsNew) {
    let points = pointsNew ? pointsNew : [
            [first, 16],
            [20, update],
            [last, 16]
        ],
        d = points.reduce((acc, point, i, a) => i === 0 ? `M ${point[0]},${point[1]}` : `${acc} ${getPoint(point, i, a, smoothing)}`, '');
    return `<path d="${d}" />`;
}

External CSS

  1. https://cdn.jsdelivr.net/npm/[email protected]/inter.min.css

External JavaScript

  1. https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js