JSFiddle - React, Tailwind, and code Playground

HTML

<body>
<div id="test">
    <div class="s">

    </div>
</div>
</body>

CSS

#test{
    margin-top: 66px;
    background-color: #ffff4f;
    width: 500px;
    height: 50px;
}

JavaScript

/**
 * Класс создающий анимацию
 * @param node
 * @param styles
 * @param options
 * @constructor
 */
function Animation(node, styles, options) {
    this.node = node;
    this.styles = styles;
    this.options = options;
    this.initValue = this.getInitValue();
    this.animatedValue = this.getAnimatedValue();
    this.timeout = 20;
    this.animatedLoop = null;
    this.isAnimationFraim = (window.requestAnimationFrame != undefined);
}

/**
 * Главный метод запускающий анимацию
 */
Animation.prototype.startAnimate = function () {
    if (!Object.keys(this.animatedValue).length) {
        throw 'No animation';
    }
    this.start = new Date().getTime();
    this.end = this.start + this.options.duratrion;
    if (this.isAnimationFraim) {
        var animation = this.animatedNewWay();
        animation();
    } else {
        this.animatedLoop = setInterval(this.animatedOldSchool.bind(this), this.timeout);
    }
};

Animation.prototype.animatedOldSchool = function () {
    if (this.makeFrame() >= 100) {
        this.stopAnimation();
    }
};

Animation.prototype.animatedNewWay = function () {
    return function animationLoop() {
        var progressPercent = this.makeFrame();
        this.animatedLoop =  requestAnimationFrame(this.animatedNewWay());
        if (progressPercent >= 100) {
            this.stopAnimation();
        }
    }.bind(this);
};

Animation.prototype.makeFrame = function() {
    var time = new Date().getTime();
    var progressPercent = 100 * (time - this.start) / this.options.duratrion;
    var currentAnimated = this.getValueByStep(progressPercent);
    this.setAnimatedValue(currentAnimated);
    if ((typeof this.options.onTick) == 'function') {
        this.options.onTick(progressPercent);
    }
    return progressPercent;
};

/**
 * Установить новые стили анимируемого объекта
 * @param animatedValue объект с новыми значениями стилей
 */
Animation.prototype.setAnimatedValue = function (animatedValue) {
    for (var prop in animatedValue)...