@cloudcome/utils-core
Version:
cloudcome core utils
152 lines (151 loc) • 5.79 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const NEWTON_ITERATIONS = 4;
const NEWTON_MIN_SLOPE = 1e-3;
const SUBDIVISION_PRECISION = 1e-7;
const SUBDIVISION_MAX_ITERATIONS = 10;
const kSplineTableSize = 11;
const kSampleStepSize = 1 / (kSplineTableSize - 1);
const float32ArraySupported = typeof Float32Array === "function";
function A(aA1, aA2) {
return 1 - 3 * aA2 + 3 * aA1;
}
function B(aA1, aA2) {
return 3 * aA2 - 6 * aA1;
}
function C(aA1) {
return 3 * aA1;
}
function calcBezier(aT, aA1, aA2) {
return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
}
function getSlope(aT, aA1, aA2) {
return 3 * A(aA1, aA2) * aT * aT + 2 * B(aA1, aA2) * aT + C(aA1);
}
function binarySubdivide(aX, aA, aB, mX1, mX2) {
let currentX;
let currentT;
let i = 0;
let aBFinal = aB;
let aAFinal = aA;
do {
currentT = aAFinal + (aBFinal - aAFinal) / 2;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0) {
aBFinal = currentT;
} else {
aAFinal = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
let aGuessTFinal = aGuessT;
for (let i = 0; i < NEWTON_ITERATIONS; ++i) {
const currentSlope = getSlope(aGuessTFinal, mX1, mX2);
if (currentSlope === 0) {
return aGuessTFinal;
}
const currentX = calcBezier(aGuessTFinal, mX1, mX2) - aX;
aGuessTFinal -= currentX / currentSlope;
}
return aGuessTFinal;
}
function LinearEasing(x) {
return x;
}
function createEasingFn(x1, y1, x2, y2) {
if (!(0 <= x1 && x1 <= 1 && 0 <= x2 && x2 <= 1)) {
throw new Error("bezier x values must be in [0, 1] range");
}
if (x1 === y1 && x2 === y2) {
return LinearEasing;
}
const sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
for (let i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, x1, x2);
}
function getTForX(aX) {
let intervalStart = 0;
let currentSample = 1;
const lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
const guessForT = intervalStart + dist * kSampleStepSize;
const initialSlope = getSlope(guessForT, x1, x2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, x1, x2);
}
if (initialSlope === 0) {
return guessForT;
}
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, x1, x2);
}
return function easingFunc(x) {
if (x === 0 || x === 1) {
return x;
}
return calcBezier(getTForX(x), y1, y2);
};
}
const easingEase = createEasingFn(0.25, 0.1, 0.25, 1);
const easingLinear = createEasingFn(0, 0, 1, 1);
const easingSnap = createEasingFn(0, 1, 0.5, 1);
const easingIn = createEasingFn(0.42, 0, 1, 1);
const easingOut = createEasingFn(0, 0, 0.58, 1);
const easingInOut = createEasingFn(0.42, 0, 0.58, 1);
const easingInQuad = createEasingFn(0.55, 0.085, 0.68, 0.53);
const easingInCubic = createEasingFn(0.55, 0.055, 0.675, 0.19);
const easingInQuart = createEasingFn(0.895, 0.03, 0.685, 0.22);
const easingInQuint = createEasingFn(0.755, 0.05, 0.855, 0.06);
const easingInSine = createEasingFn(0.47, 0, 0.745, 0.715);
const easingInExpo = createEasingFn(0.95, 0.05, 0.795, 0.035);
const easingInCirc = createEasingFn(0.6, 0.04, 0.98, 0.335);
const easingInBack = createEasingFn(0.6, -0.28, 0.735, 0.045);
const easingOutQuad = createEasingFn(0.25, 0.46, 0.45, 0.94);
const easingOutCubic = createEasingFn(0.215, 0.61, 0.355, 1);
const easingOutQuart = createEasingFn(0.165, 0.84, 0.44, 1);
const easingOutQuint = createEasingFn(0.23, 1, 0.32, 1);
const easingOutSine = createEasingFn(0.39, 0.575, 0.565, 1);
const easingOutExpo = createEasingFn(0.19, 1, 0.22, 1);
const easingOutCirc = createEasingFn(0.075, 0.82, 0.165, 1);
const easingOutBack = createEasingFn(0.175, 0.885, 0.32, 1.275);
const easingInOutQuart = createEasingFn(0.77, 0, 0.175, 1);
const easingInOutQuint = createEasingFn(0.86, 0, 0.07, 1);
const easingInOutSine = createEasingFn(0.445, 0.05, 0.55, 0.95);
const easingInOutExpo = createEasingFn(1, 0, 0, 1);
const easingInOutCirc = createEasingFn(0.785, 0.135, 0.15, 0.86);
const easingInOutBack = createEasingFn(0.68, -0.55, 0.265, 1.55);
exports.createEasingFn = createEasingFn;
exports.easingEase = easingEase;
exports.easingIn = easingIn;
exports.easingInBack = easingInBack;
exports.easingInCirc = easingInCirc;
exports.easingInCubic = easingInCubic;
exports.easingInExpo = easingInExpo;
exports.easingInOut = easingInOut;
exports.easingInOutBack = easingInOutBack;
exports.easingInOutCirc = easingInOutCirc;
exports.easingInOutExpo = easingInOutExpo;
exports.easingInOutQuart = easingInOutQuart;
exports.easingInOutQuint = easingInOutQuint;
exports.easingInOutSine = easingInOutSine;
exports.easingInQuad = easingInQuad;
exports.easingInQuart = easingInQuart;
exports.easingInQuint = easingInQuint;
exports.easingInSine = easingInSine;
exports.easingLinear = easingLinear;
exports.easingOut = easingOut;
exports.easingOutBack = easingOutBack;
exports.easingOutCirc = easingOutCirc;
exports.easingOutCubic = easingOutCubic;
exports.easingOutExpo = easingOutExpo;
exports.easingOutQuad = easingOutQuad;
exports.easingOutQuart = easingOutQuart;
exports.easingOutQuint = easingOutQuint;
exports.easingOutSine = easingOutSine;
exports.easingSnap = easingSnap;
//# sourceMappingURL=easing.cjs.map