summaryrefslogtreecommitdiff
path: root/client/vendor/oktransition.js
diff options
context:
space:
mode:
Diffstat (limited to 'client/vendor/oktransition.js')
-rw-r--r--client/vendor/oktransition.js182
1 files changed, 182 insertions, 0 deletions
diff --git a/client/vendor/oktransition.js b/client/vendor/oktransition.js
new file mode 100644
index 0000000..816ffb0
--- /dev/null
+++ b/client/vendor/oktransition.js
@@ -0,0 +1,182 @@
+/*
+ oktransition.add({
+ obj: el.style,
+ units: "px",
+ from: { left: 0 },
+ to: { left: 100 },
+ duration: 1000,
+ easing: oktransition.easing.circ_out,
+ update: function(obj){
+ console.log(obj.left)
+ }
+ finished: function(){
+ console.log("done")
+ }
+ })
+*/
+
+const oktransition = {};
+let transitions = [];
+
+let last_t = 0;
+let id = 0;
+
+const lerp = (n, a, b) => (b - a) * n + a;
+
+oktransition.speed = 1;
+oktransition.add = (transition) => {
+ transition.id = id++;
+ transition.obj = transition.obj || {};
+ if (transition.easing) {
+ if (typeof transition.easing === "string") {
+ transition.easing = oktransition.easing[transition.easing];
+ }
+ } else {
+ transition.easing = oktransition.easing.linear;
+ }
+ if (!("from" in transition) && !("to" in transition)) {
+ transition.keys = [];
+ } else if (!("from" in transition)) {
+ transition.from = {};
+ transition.keys = Object.keys(transition.to);
+ transition.keys.forEach(function (prop) {
+ transition.from[prop] = parseFloat(transition.obj[prop]);
+ });
+ } else {
+ transition.keys = Object.keys(transition.from);
+ }
+ transition.delay = transition.delay || 0;
+ transition.start = last_t + transition.delay;
+ transition.done = false;
+ transition.after = transition.after || [];
+ transition.then = (fn) => {
+ transition.after.push(fn);
+ return transition;
+ };
+ transition.tick = 0;
+ transition.skip = transition.skip || 1;
+ transition.dt = 0;
+ transition.cancel = () =>
+ (transitions = transitions.filter((item) => item !== transition));
+ transitions.push(transition);
+ return transition;
+};
+oktransition.update = (t) => {
+ let done = false;
+ requestAnimationFrame(oktransition.update);
+ last_t = t * oktransition.speed;
+ if (transitions.length === 0) return;
+ transitions.forEach((transition, i) => {
+ const dt = Math.min(1.0, (t - transition.start) / transition.duration);
+ transition.tick++;
+ if (
+ dt < 0 ||
+ (dt < 1 && transition.tick % transition.skip != 0) ||
+ transition.done
+ )
+ return;
+ const ddt = transition.easing(dt);
+ transition.dt = ddt;
+ transition.keys.forEach((prop) => {
+ let val = lerp(ddt, transition.from[prop], transition.to[prop]);
+ if (transition.round) val = Math.round(val);
+ if (transition.units) val = Math.round(val) + transition.units;
+ transition.obj[prop] = val;
+ });
+ if (transition.update) {
+ transition.update(transition.obj, dt);
+ }
+ if (dt === 1) {
+ if (transition.finished) {
+ transition.finished(transition);
+ }
+ if (transition.after.length) {
+ const twn = transition.after.shift();
+ twn.obj = twn.obj || transition.obj;
+ twn.after = transition.after;
+ oktransition.add(twn);
+ }
+ if (transition.loop) {
+ transition.start = t + transition.delay;
+ } else {
+ done = true;
+ transition.done = true;
+ }
+ }
+ });
+ if (done) {
+ transitions = transitions.filter((transition) => !transition.done);
+ }
+};
+
+requestAnimationFrame(oktransition.update);
+
+oktransition.easing = {
+ linear: (t) => {
+ return t;
+ },
+ circ_out: (t) => {
+ return Math.sqrt(1 - (t = t - 1) * t);
+ },
+ circ_in: (t) => {
+ return -(Math.sqrt(1 - t * t) - 1);
+ },
+ circ_in_out: (t) => {
+ return (t *= 2) < 1
+ ? -0.5 * (Math.sqrt(1 - t * t) - 1)
+ : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);
+ },
+ quad_in: (n) => {
+ return Math.pow(n, 2);
+ },
+ quad_out: (n) => {
+ return n * (n - 2) * -1;
+ },
+ quad_in_out: (n) => {
+ n = n * 2;
+ if (n < 1) {
+ return Math.pow(n, 2) / 2;
+ }
+ return (-1 * (--n * (n - 2) - 1)) / 2;
+ },
+ cubic_bezier: (mX1, mY1, mX2, mY2) => {
+ function A(aA1, aA2) {
+ return 1.0 - 3.0 * aA2 + 3.0 * aA1;
+ }
+ function B(aA1, aA2) {
+ return 3.0 * aA2 - 6.0 * aA1;
+ }
+ function C(aA1) {
+ return 3.0 * aA1;
+ }
+
+ // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+ function CalcBezier(aT, aA1, aA2) {
+ return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+ }
+
+ // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+ function GetSlope(aT, aA1, aA2) {
+ return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+ }
+
+ function GetTForX(aX) {
+ // Newton raphson iteration
+ let aGuessT = aX;
+ for (let i = 0; i < 10; ++i) {
+ const currentSlope = GetSlope(aGuessT, mX1, mX2);
+ if (currentSlope == 0.0) return aGuessT;
+ const currentX = CalcBezier(aGuessT, mX1, mX2) - aX;
+ aGuessT -= currentX / currentSlope;
+ }
+ return aGuessT;
+ }
+
+ return function (aX) {
+ if (mX1 == mY1 && mX2 == mY2) return aX; // linear
+ return CalcBezier(aX, mY1, mY2);
+ };
+ },
+};
+
+export default oktransition;