JSFiddle - React, Tailwind, and code Playground

by Valentin Sarychev

HTML

<pre id="log"></pre>
<button onclick="stopAnimation()">
  Stop
</button>

CSS

#log {
  height: 300px;
  width: 300px;
}

JavaScript

const sleep = async (duration, cancellationPromise) => {
    let timer;
    try {
        await new Promise((resolve, reject) => {
            cancellationPromise && cancellationPromise.then(resolve, reject);
            timer = window.setTimeout(resolve, duration);
        });
    }
    finally {
        window.clearTimeout(timer);
    }
};
const startMySexyAnimation = async (cancellationPromise) => {
    try {
        for (let cycle = 1; cycle < 1000; cycle++) {
            console.log(`cycle #${cycle}`);
            await sleep(300, cancellationPromise);
            console.log(`move element`);
            await sleep(300, cancellationPromise);
            console.log(`rotate element`);
            await sleep(300, cancellationPromise);
            console.log(`scale element`);
            await sleep(300, cancellationPromise);
        }
    }
    catch (e) {
        console.log(`restore element`);
    }
};
// ============ usage ============
let stopMySexyAnimation;
startMySexyAnimation(new Promise((resolve, reject) => stopMySexyAnimation = reject));
setTimeout(() => {
    stopMySexyAnimation();
}, 2000);