JSFiddle - React, Tailwind, and code Playground

by darthdeus

HTML

<div class="box" id="linear"></div>
<div class="box" id="quadratic-in"></div>
<div class="box" id="quadratic-out"></div>

<button>Start animation!</button>

CSS

.box {
  background: red;
  position: fixed;
  width: 20px;
  height: 20px;
  top: 10px;
  left: 0px;
}

#quadratic-in {
  top: 35px;
}

#quadratic-out {
  top: 60px;
}

button {
  position: fixed;
  top: 90px;
}

JavaScript

var EasingFunctions = {
    LINEAR: function(t) { return t; },
    QUADRATIC_IN: function(t) { return t*t; },
    QUADRATIC_OUT: function(t) { return t*(2 - t); }
};

var Tween = {
    tweens: [],

    add: function(from, to, time, callback, easingFunction) {
        var tween = {
            time: time,
            callback: callback,
            progress: 0,
            // If no easing function is specified we default to a linear one.
            easingFunction: easingFunction || EasingFunctions.LINEAR
        };

        tween.cancel = function() { tween.cancellationRequested = true; };

        if (typeof from === "number" && typeof to === "number") {
            tween.type = "number";
            tween.from = from;
            tween.diff = to - from;
        } else {
            tween.type = "object";
            tween.from = from;

            var diff = {};

            Object.keys(to).map(function(key) {
                diff[key] = to[key] - from[key];
            });

            tween.diff = diff;
        }

        Tween.tweens.push(tween);
    },

    update: function(dt) {
        Tween.tweens = Tween.tweens.filter(function(tween) {
            if (tween.cancellationRequested) {
                return false;
            }

            tween.progress = Math.min(1, tween.progress + dt / tween.time);
            
            var t = tween.easingFunction(tween.progress);

            if (tween.type === "object") {
                var value = {};

                Object.keys(tween.diff).map(function(key) {
                    value[key] = tween.from[key] + tween.diff[key] * t;
                });

                tween.callback(value, tween.progress);
            } else if (tween.type === "number") {
                tween.callback(tween.from + tween.diff * t, tween.progress);
            } else {
                throw "Invalid tween.type " + tween.type;
            }
           

            return tween.progress < 1;
        });
    },
};

var lastFrame...