@thi.ng/ramp
Version:
Extensible keyframe interpolation/tweening of arbitrary, nested types
37 lines (36 loc) • 1.32 kB
JavaScript
import { norm } from "@thi.ng/math/fit";
import { mixCubicHermite, tangentCardinal } from "@thi.ng/math/mix";
import { mixHermiteCardinal } from "@thi.ng/vectors/mix-hermite";
import { Ramp } from "./ramp.js";
const hermite = (stops, opts) => new Ramp(HERMITE_N, stops, opts);
const HERMITE_N = {
min: (acc, x) => Math.min(acc ?? Infinity, x),
max: (acc, x) => Math.max(acc ?? -Infinity, x),
at: (stops, i, t) => {
const n = stops.length - 1;
const a = stops[Math.max(i - 1, 0)];
const [bx, by] = stops[Math.max(i, 0)];
const [cx, cy] = stops[Math.min(i + 1, n)];
const d = stops[Math.min(i + 2, n)];
const t1 = tangentCardinal(a[1], cy, 0, a[0], cx);
const t2 = tangentCardinal(by, d[1], 0, bx, d[0]);
return mixCubicHermite(by, t1, cy, t2, norm(t, bx, cx));
}
};
const HERMITE_V = (vec) => ({
min: (acc, x) => vec.min(acc, acc || vec.vecOf(Infinity), x),
max: (acc, x) => vec.max(acc, acc || vec.vecOf(-Infinity), x),
at: (stops, i, t) => {
const n = stops.length - 1;
const [, a] = stops[Math.max(i - 1, 0)];
const [bt, b] = stops[Math.max(i, 0)];
const [ct, c] = stops[Math.min(i + 1, n)];
const [, d] = stops[Math.min(i + 2, n)];
return mixHermiteCardinal([], a, b, c, d, norm(t, bt, ct), 0);
}
});
export {
HERMITE_N,
HERMITE_V,
hermite
};