<button class="button">
    <span class="handle">
        <svg class="background" viewBox="0 0 40 40">
            <path d="M5 16C5 9.92487 9.92487 5 16 5H24C30.0751 5 35 9.92487 35 16C35 16 35 18.4379 35 20C35 21.5621 35 24 35 24C35 30.0751 30.0751 35 24 35H16C9.92487 35 5 30.0751 5 24C5 24 5 21.5621 5 20C5 18.4379 5 16 5 16Z"></path>
        </svg>
        <svg class="icon" viewBox="0 0 20 20">
            <polyline points="9 13 12 10 8 6"></polyline>
        </svg>
    </span>
    <span class="default">Buy now</span>
    <span class="progress">Confirm</span>
    <span class="success">Done</span>
    <span class="drop">
        <svg class="background" viewBox="0 0 40 40">
            <path d="M5 16C5 9.92487 9.92487 5 16 5H24C30.0751 5 35 9.92487 35 16C35 16 35 18.4379 35 20C35 21.5621 35 24 35 24C35 30.0751 30.0751 35 24 35H16C9.92487 35 5 30.0751 5 24C5 24 5 21.5621 5 20C5 18.4379 5 16 5 16Z"></path>
        </svg>
    </span>
</button>

<!-- dribbble - twitter -->
<a class="dribbble" href="https://dribbble.com/ai" target="_blank"><img src="https://cdn.dribbble.com/assets/dribbble-ball-mark-2bd45f09c2fb58dbbfb44766d5d1d07c5a12972d602ef8b32204d28fa3dda554.svg" alt=""></a>
<a class="twitter" target="_blank" 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 {
    --text: #FFFFFF;
    --background: #275EFE;
    --background-opacity: 1;
    --handle-stroke: #{rgba(#fff, .8)};
    --handle-fill: #{rgba(#fff, .08)};
    --handle-blur: 2;
    --drop-stroke: #{rgba(#fff, .2)};
    --drop-fill: #{rgba(#fff, 0)};
    --icon-stroke: #FFFFFF;
    --icon-rotate: 0;
    --icon-scale: 1;
    --icon-y: 0;
    --icon-offset: 16.8;
    --handle-drop-opacity: 0;
    --default-opacity: 1;
    --default-x: 0;
    --default-scale: 1;
    --progress-opacity: 0;
    --progress-scale: .75;
    --success-opacity: 0;
    --success-x: 0;
    --success-scale: .75;
    display: block;
    cursor: pointer;
    position: relative;
    text-align: center;
    outline: none;
    border: none;
    overflow: hidden;
    padding: 8px 0;
    margin: 0;
    width: 148px;
    line-height: 30px;
    font-family: inherit;
    font-weight: 600;
    border-radius: 16px;
    color: var(--text);
    background: var(--background);
    transform: scale(var(--button-scale, 1)) translateZ(0);
    transition: transform .15s;
    -webkit-appearance: none;
    -webkit-tap-highlight-color: transparent;
    .handle,
    .progress,
    .success,
    .drop {
        position: absolute;
        left: var(--left, auto);
        right: var(--right, auto);
        top: var(--top, auto);
    }
    .handle {
        -webkit-backdrop-filter: blur(calc(var(--handle-blur) * 1px));
        backdrop-filter: blur(calc(var(--handle-blur) * 1px));
    }
    .handle,
    .drop {
        --top: 8px;
        z-index: 1;
        border-radius: 11px;
        opacity: var(--handle-drop-opacity);
        pointer-events: var(--handle-drop-pointer, auto);
        svg {
            display: block;
            width: var(--svg-size, 40px);
            height: var(--svg-size, 40px);
            stroke-width: 1px;
            stroke: var(--stroke, var(--handle-stroke));
            fill: var(--fill, var(--handle-fill));
            &.background {
                margin: -5px;
                opacity: var(--background-opacity);
            }
            &.icon {
                --svg-size: 20px;
                --fill: none;
                --stroke: var(--icon-stroke);
                position: absolute;
                left: 5px;
                top: 5px;
                stroke-width: 1.25;
                stroke-linecap: round;
                stroke-linejoin: round;
                stroke-dasharray: 8.5;
                stroke-dashoffset: var(--icon-offset);
                transform: translateY(calc(var(--icon-y) * 1px)) rotate(calc(var(--icon-rotate) * 1deg)) scale(var(--icon-scale)) translateZ(0);
            }
        }
    }
    .handle {
        --left: 8px;
    }
    .drop {
        --right: 8px;
        --stroke: var(--drop-stroke);
        --fill: var(--drop-fill);
    }
    .default,
    .progress,
    .success {
        display: block;
        font-size: var(--font-size, 14px);
        opacity: var(--opacity, var(--default-opacity));
        transform: translateX(calc(var(--x, var(--default-x)) * 1px)) scale(var(--scale, var(--default-scale))) translateZ(0);
    }
    .progress,
    .success {
        --left: 0;
        --right: 0;
        --top: 8px;
    }
    .progress {
        --font-size: 11px;
        --opacity: var(--progress-opacity);
        --scale: var(--progress-scale);
    }
    .success {
        --font-size: 14px;
        --opacity: var(--success-opacity);
        --x: var(--success-x);
        --scale: var(--success-scale);
    }
    &:not(.active) {
        --handle-drop-pointer: none;
        &:active {
            --button-scale: .975;
        }
    }
}

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

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


// Center & dribbble
body {
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    font-family: 'Inter', Arial;
    background: #E1E6F9;
    .dribbble {
        position: fixed;
        display: block;
        right: 20px;
        bottom: 20px;
        img {
            display: block;
            height: 28px;
        }
    }
    .twitter {
        position: fixed;
        display: block;
        right: 64px;
        bottom: 14px;
        svg {
            width: 32px;
            height: 32px;
            fill: #1da1f2;
        }
    }
}
View Compiled
gsap.registerPlugin(Draggable, MorphSVGPlugin);

document.querySelectorAll('.button').forEach(button => {

    let handle = button.querySelector('.handle'),
        handlePath = handle.querySelector('.background path'),
        drop = button.querySelector('.drop'),
        dropPath = drop.querySelector('.background path');

    let handleTween = gsap.to(handlePath, {
        paused: true,
        morphSVG: 'M5 16C5 9.92487 9.92487 5 16 5H24C30.0751 5 34 9.92487 36 16C36 16 37 18.4379 37 20C37 21.5621 36 24 36 24C34 30.0751 30.0751 35 24 35H16C9.92487 35 5 30.0751 5 24C5 24 5 21.5621 5 20C5 18.4379 5 16 5 16Z'
    });

    let dropTween = gsap.to(dropPath, {
        paused: true,
        morphSVG: 'M4 16C6 9.92487 9.92487 5 16 5H24C30.0751 5 35 9.92487 35 16C35 16 35 18.4379 35 20C35 21.5621 35 24 35 24C35 30.0751 30.0751 35 24 35H16C9.92487 35 6 30.0751 4 24C4 24 3 21.5621 3 20C3 18.4379 4 16 4 16Z'
    });
    
    gsap.set(handle, {
        x: 0
    });

    Draggable.create(handle, {
        type: 'x',
        bounds: button,
        onDrag(e) {
            dragging(this.x, button, handle, drop, handleTween, dropTween);
        },
        onRelease(e) {
            if(!this.hitTest(drop)) {
                gsap.to(handle, {
                    x: 0,
                    duration: .6,
                    ease: 'elastic.out(1, .75)',
                    onUpdate(e) {
                        dragging(gsap.getProperty(handle, 'x'), button, handle, drop, handleTween, dropTween);
                    }
                });
                if(gsap.getProperty(handle, 'x') > 0) {
                    gsap.to(handlePath, {
                        keyframes: [{
                            morphSVG: 'M5 16C5 9.92487 9.92487 5 16 5H24C30.0751 5 37 9.92487 35 16C35 16 34 18.4379 34 20C34 21.5621 35 24 35 24C37 30.0751 30.0751 35 24 35H16C9.92487 35 5 30.0751 5 24C5 24 5 21.5621 5 20C5 18.4379 5 16 5 16Z',
                            duration: .2
                        }, {
                            morphSVG: 'M5 16C5 9.92487 9.92487 5 16 5H24C30.0751 5 35 9.92487 35 16C35 16 35 18.4379 35 20C35 21.5621 35 24 35 24C35 30.0751 30.0751 35 24 35H16C9.92487 35 5 30.0751 5 24C5 24 5 21.5621 5 20C5 18.4379 5 16 5 16Z',
                            duration: .3
                        }]
                    });
                }
            } else {
                this.disable()
                gsap.to(handle, {
                    keyframes: [{
                        x: drop.offsetLeft - 8,
                        duration: .6,
                        ease: 'elastic.out(1, .8)'
                    }, {
                        x: button.offsetWidth / 2 - handle.offsetWidth - 20,
                        duration: .3
                    }]
                });
                gsap.to(handlePath, {
                    keyframes: [{
                        morphSVG: 'M5 16C3 9.92487 9.92487 5 16 5H24C30.0751 5 35 9.92487 35 16C35 16 35 18.4379 35 20C35 21.5621 35 24 35 24C35 30.0751 30.0751 35 24 35H16C9.92487 35 3 30.0751 5 24C5 24 6 21.5621 6 20C6 18.4379 5 16 5 16Z',
                        duration: .2
                    }, {
                        morphSVG: 'M5 16C5 9.92487 9.92487 5 16 5H24C30.0751 5 35 9.92487 35 16C35 16 35 18.4379 35 20C35 21.5621 35 24 35 24C35 30.0751 30.0751 35 24 35H16C9.92487 35 5 30.0751 5 24C5 24 5 21.5621 5 20C5 18.4379 5 16 5 16Z',
                        duration: .15
                    }]
                });
                gsap.to(button, {
                    '--background-opacity': 0,
                    '--progress-opacity': 0,
                    '--handle-blur': 0,
                    '--icon-y': .5,
                    duration: .3,
                    delay: .2
                });
                gsap.to(button, {
                    '--icon-rotate': 87,
                    '--icon-offset': 15.5,
                    '--icon-scale': 1.5,
                    duration: .25,
                    delay: .3
                });
                gsap.to(button, {
                    '--success-opacity': 1,
                    '--success-scale': 1,
                    '--success-x': 8,
                    duration: .2,
                    delay: .8
                });
            }
        }
    });

    button.addEventListener('click', e => {

        if(button.classList.contains('active')) {
            return
        }

        button.classList.add('active');

        gsap.to(button, {
            '--handle-drop-opacity': 1,
            '--default-opacity': 0,
            '--default-scale': .8,
            duration: .2
        })
        gsap.to(button, {
            '--progress-opacity': .5,
            '--progress-scale': 1,
            duration: .2,
            delay: .15
        })

    });

});

function dragging(x, button, handle, drop, handleTween, dropTween) {
    let progress = button.offsetWidth - 16 - handle.offsetWidth - drop.offsetWidth - x - 8;

    progress = (12 - (progress > 12 ? 12 : progress < -12 ? -12 : progress)) / 12;
    progress = progress > 1 ? 2 - progress : progress;

    handleTween.progress(progress);
    dropTween.progress(progress);
}

External CSS

  1. https://fonts.googleapis.com/css?family=Inter:400,500,600,700&amp;display=swap

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.6/gsap.min.js
  2. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin3.min.js
  3. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/Draggable3.min.js