UNPKG

5.07 kBJavaScriptView Raw
1"use strict";
2// Taken from https://github.com/facebook/react-native/blob/0b9ea60b4fee8cacc36e7160e31b91fc114dbc0d/Libraries/Animated/src/nodes/AnimatedInterpolation.js
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.interpolate = void 0;
5function interpolateFunction(input, inputRange, outputRange, options) {
6 const { extrapolateLeft, extrapolateRight, easing } = options;
7 let result = input;
8 const [inputMin, inputMax] = inputRange;
9 const [outputMin, outputMax] = outputRange;
10 if (result < inputMin) {
11 if (extrapolateLeft === 'identity') {
12 return result;
13 }
14 if (extrapolateLeft === 'clamp') {
15 result = inputMin;
16 }
17 else if (extrapolateLeft === 'extend') {
18 // noop
19 }
20 }
21 if (result > inputMax) {
22 if (extrapolateRight === 'identity') {
23 return result;
24 }
25 if (extrapolateRight === 'clamp') {
26 result = inputMax;
27 }
28 else if (extrapolateRight === 'extend') {
29 // noop
30 }
31 }
32 if (outputMin === outputMax) {
33 return outputMin;
34 }
35 // Input Range
36 result = (result - inputMin) / (inputMax - inputMin);
37 // Easing
38 result = easing(result);
39 // Output Range
40 result = result * (outputMax - outputMin) + outputMin;
41 return result;
42}
43function findRange(input, inputRange) {
44 let i;
45 for (i = 1; i < inputRange.length - 1; ++i) {
46 if (inputRange[i] >= input) {
47 break;
48 }
49 }
50 return i - 1;
51}
52function checkValidInputRange(arr) {
53 for (let i = 1; i < arr.length; ++i) {
54 if (!(arr[i] > arr[i - 1])) {
55 throw new Error(`inputRange must be strictly monotonically non-decreasing but got [${arr.join(',')}]`);
56 }
57 }
58}
59function checkInfiniteRange(name, arr) {
60 if (arr.length < 2) {
61 throw new Error(name + ' must have at least 2 elements');
62 }
63 for (const index in arr) {
64 if (typeof arr[index] !== 'number') {
65 throw new Error(`${name} must contain only numbers`);
66 }
67 if (arr[index] === -Infinity || arr[index] === Infinity) {
68 throw new Error(`${name} must contain only finite numbers, but got [${arr.join(',')}]`);
69 }
70 }
71}
72/**
73 * Map a value from an input range to an output range.
74 * @link https://www.remotion.dev/docs/interpolate
75 * @param {!number} input value to interpolate
76 * @param {!number[]} inputRange range of values that you expect the input to assume.
77 * @param {!number[]} outputRange range of output values that you want the input to map to.
78 * @param {?object} options
79 * @param {?Function} options.easing easing function which allows you to customize the input, for example to apply a certain easing function. By default, the input is left unmodified, resulting in a pure linear interpolation {@link https://www.remotion.dev/docs/easing}
80 * @param {string=} [options.extrapolateLeft="extend"] What should happen if the input value is outside left the input range, default: "extend" {@link https://www.remotion.dev/docs/interpolate#extrapolateleft}
81 * @param {string=} [options.extrapolateRight="extend"] Same as extrapolateLeft, except for values outside right the input range {@link https://www.remotion.dev/docs/interpolate#extrapolateright}
82 */
83function interpolate(input, inputRange, outputRange, options) {
84 var _a;
85 if (typeof input === 'undefined') {
86 throw new Error('input can not be undefined');
87 }
88 if (typeof inputRange === 'undefined') {
89 throw new Error('inputRange can not be undefined');
90 }
91 if (typeof outputRange === 'undefined') {
92 throw new Error('outputRange can not be undefined');
93 }
94 if (inputRange.length !== outputRange.length) {
95 throw new Error('inputRange (' +
96 inputRange.length +
97 ') and outputRange (' +
98 outputRange.length +
99 ') must have the same length');
100 }
101 checkInfiniteRange('inputRange', inputRange);
102 checkInfiniteRange('outputRange', outputRange);
103 checkValidInputRange(inputRange);
104 const easing = (_a = options === null || options === void 0 ? void 0 : options.easing) !== null && _a !== void 0 ? _a : ((num) => num);
105 let extrapolateLeft = 'extend';
106 if ((options === null || options === void 0 ? void 0 : options.extrapolateLeft) !== undefined) {
107 extrapolateLeft = options.extrapolateLeft;
108 }
109 let extrapolateRight = 'extend';
110 if ((options === null || options === void 0 ? void 0 : options.extrapolateRight) !== undefined) {
111 extrapolateRight = options.extrapolateRight;
112 }
113 if (typeof input !== 'number') {
114 throw new TypeError('Cannot interpolate an input which is not a number');
115 }
116 const range = findRange(input, inputRange);
117 return interpolateFunction(input, [inputRange[range], inputRange[range + 1]], [outputRange[range], outputRange[range + 1]], {
118 easing,
119 extrapolateLeft,
120 extrapolateRight,
121 });
122}
123exports.interpolate = interpolate;