<div class='blobs-container'>
    <div class='blob-example'>
        <svg class='svg' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>
            <path class='animatedpath' fill='#FF0066' transform='translate(100 100)' />
        </svg>
    </div>
    <div class='blob-example'>
        <svg class='svg' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>
            <path class='animatedpath' fill='#FF0066' transform='translate(100 100)' />
        </svg>
    </div>
    <div class='blob-example'>
        <svg class='svg' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>
            <path class='animatedpath' fill='#FF0066' transform='translate(100 100)' />
        </svg>
    </div>
    <div class='blob-example'>
        <svg class='svg' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>
            <path class='animatedpath' fill='#FF0066' transform='translate(100 100)' />
        </svg>
    </div>
    <div class='blob-example'>
        <svg class='svg' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>
            <path class='animatedpath' fill='#FF0066' transform='translate(100 100)' />
        </svg>
    </div>
    <div class='blob-example'>
        <svg class='svg' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>
            <path class='animatedpath' fill='#FF0066' transform='translate(100 100)' />
        </svg>
    </div>
    <div class='blob-example'>
        <svg class='svg' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>
            <path class='animatedpath' fill='#FF0066' transform='translate(100 100)' />
        </svg>
    </div>
</div>

<script src='https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js'></script>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    overflow: hidden;
    background: #344e41;
}

.blobs-container {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
    height: 100vmin;
    width: 100vmin;
}

.blob-example {
    position: absolute;
    height: 30%;
    width: 30%;
    border-radius: 50%;
    overflow: hidden;
    background: #a3b18a;
    transform: translateX(-50%) translateY(-50%);
}

.blob-example > .svg {
    height: 100%;
    width: 100%;
}

.blob-example > .svg > .animatedpath {
    fill: #3a5a40;
}

.blob-example:nth-of-type(1) {
    top: 10%;
    left: 10%;
    height: 100%;
    width: 100%;
}

.blob-example:nth-of-type(2) {
    top: 37%;
    left: 90%;
    height: 60%;
    width: 60%;
}

.blob-example:nth-of-type(3) {
    top: 90%;
    left: 80%;
    height: 40%;
    width: 40%;
}

.blob-example:nth-of-type(4) {
    top: 95%;
    left: 45%;
    height: 20%;
    width: 20%;
}

.blob-example:nth-of-type(5) {
    top: 80%;
    left: 30%;
    height: 15%;
    width: 15%;
}

.blob-example:nth-of-type(6) {
    top: 65%;
    left: 40%;
    height: 10%;
    width: 10%;
}

.blob-example:nth-of-type(7) {
    top: 70%;
    left: 50%;
    height: 5%;
    width: 5%;
}
// Blobs from https://www.blobmaker.app/

const BLOBS = [
    'M60.4,-61.3C74.5,-46.3,79.6,-23.1,76.9,-2.7C74.2,17.8,63.8,35.6,49.7,51.3C35.6,66.9,17.8,80.4,-2.2,82.6C-22.3,84.9,-44.6,75.9,-60.7,60.3C-76.8,44.6,-86.7,22.3,-85,1.7C-83.3,-18.8,-69.9,-37.7,-53.8,-52.7C-37.7,-67.7,-18.8,-78.8,2.1,-81C23.1,-83.1,46.3,-76.3,60.4,-61.3Z',
    'M47.3,-50.3C60.4,-34.2,69.4,-17.1,66.1,-3.4C62.7,10.4,46.9,20.7,33.8,35.7C20.7,50.6,10.4,70.2,-6.5,76.7C-23.4,83.2,-46.8,76.8,-54,61.8C-61.3,46.8,-52.2,23.4,-45.4,6.8C-38.6,-9.8,-33.9,-19.5,-26.7,-35.7C-19.5,-51.8,-9.8,-74.3,3.7,-78C17.1,-81.6,34.2,-66.4,47.3,-50.3Z',
    'M57.1,-48.1C70.9,-43.3,76.7,-21.7,69.7,-7.1C62.6,7.5,42.5,15,28.8,20.8C15,26.5,7.5,30.5,-6.2,36.8C-20,43,-40,51.5,-49.8,45.7C-59.6,40,-59.3,20,-58.3,1C-57.3,-17.9,-55.5,-35.9,-45.7,-40.7C-35.9,-45.5,-17.9,-37.2,1.9,-39.1C21.7,-40.9,43.3,-53,57.1,-48.1Z',
    'M43.9,-43C59,-28.8,74.9,-14.4,76.8,1.9C78.6,18.1,66.5,36.2,51.4,52.5C36.2,68.7,18.1,83,-2,85C-22.1,87,-44.2,76.7,-49.5,60.5C-54.7,44.2,-43,22.1,-40.3,2.7C-37.6,-16.8,-44,-33.6,-38.8,-47.8C-33.6,-62.1,-16.8,-73.8,-1.2,-72.6C14.4,-71.4,28.8,-57.3,43.9,-43Z',
    'M53.9,-47.2C70.2,-37.7,83.8,-18.8,77.8,-6C71.8,6.9,46.2,13.7,30,21.4C13.7,29.1,6.9,37.5,-2.9,40.4C-12.6,43.2,-25.2,40.5,-39,32.9C-52.7,25.2,-67.6,12.6,-63.3,4.2C-59.1,-4.2,-35.8,-8.3,-22.1,-17.8C-8.3,-27.3,-4.2,-42.2,7.3,-49.5C18.8,-56.8,37.7,-56.7,53.9,-47.2Z',
    'M51.8,-59.2C60.9,-42.7,57.8,-21.3,56.8,-1C55.8,19.3,56.8,38.6,47.7,47.2C38.6,55.9,19.3,53.9,1.2,52.7C-16.9,51.5,-33.7,51.1,-49.2,42.4C-64.6,33.7,-78.6,16.9,-78.2,0.3C-77.9,-16.2,-63.2,-32.3,-47.8,-48.9C-32.3,-65.4,-16.2,-82.4,2.6,-85C21.3,-87.5,42.7,-75.8,51.8,-59.2Z',
    'M40.3,-33.3C56.7,-24,77.5,-12,81.7,4.2C85.9,20.4,73.5,40.8,57.1,48.8C40.8,56.8,20.4,52.4,-0.4,52.9C-21.3,53.3,-42.5,58.6,-50.5,50.6C-58.5,42.5,-53.1,21.3,-50.4,2.7C-47.7,-15.8,-47.5,-31.6,-39.5,-40.9C-31.6,-50.2,-15.8,-53.1,-1.9,-51.2C12,-49.3,24,-42.6,40.3,-33.3Z',
];

class Blob {
    #root;
    #path;
    #d1;
    #d2;
    #animation;

    constructor(options) {
        this.#root = options.root;
        this.#path = this.#root.querySelector('.animatedpath');
        this.#d1 = options.d1;
        this.#d2 = options.d2;

        this.#path.setAttribute('d', this.#d1);

        this.#animation = anime({
            targets: this.#path,
            d: [
                { value: this.#d1, duration: 0 },
                { value: this.#d2 },
            ],
            direction: 'reverse',
            duration: 1500,
            easing: 'easeInOutElastic(1, .6)',
            autoplay: false,
        });

        this.#animation.seek(10);

        this.#initEventListeners();
    }

    #initEventListeners() {
        this.#root.addEventListener('mouseenter', () => {
            this.#animation.reverse();
            this.#animation.play();
        });

        this.#root.addEventListener('mouseleave', () => {
            this.#animation.reverse();
            this.#animation.play();
        });
    }
}

function main() {
    const blobRoots = document.querySelectorAll('.blob-example');
    const blobs = [];

    blobRoots.forEach((root, index) => {
        const N = BLOBS.length;
        const index2 = (index - 1 + N) % N;
        const d1 = BLOBS[index];
        const d2 = BLOBS[index2];
        
        const blob = new Blob({ root, d1, d2 });

        blobs.push(blob);
    });
}

document.addEventListener('DOMContentLoaded', main);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.