UNPKG

@thi.ng/ramp

Version:

Extensible keyframe interpolation/tweening of arbitrary, nested types

37 lines (36 loc) 1.32 kB
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 };