Skip to content

Instantly share code, notes, and snippets.

@jossmac
Created May 19, 2018 02:19
Show Gist options
  • Save jossmac/06305dc1c1712235325cec3caacd6f62 to your computer and use it in GitHub Desktop.
Save jossmac/06305dc1c1712235325cec3caacd6f62 to your computer and use it in GitHub Desktop.
/**
* Clamp value between
* Creates a function that will restrict a given value between `min` and `max`
* @param {number} min
* @param {number} max
* @return {number}
*/
const clamp = (min, max) => (v) => Math.min(Math.max(v, min), max);
/*
Progress within given range
Given a lower limit and an upper limit, we return the progress
(expressed as a number 0-1) represented by the given value, and
limit that progress to within 0-1.
@param [number]: Lower limit
@param [number]: Upper limit
@param [number]: Value to find progress within given range
@return [number]: Progress of value within range as expressed 0-1
*/
const getProgressFromValue = (from, to, value) => {
const toFromDifference = to - from;
return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
}
/*
Value in range from progress
Given a lower limit and an upper limit, we return the value within
that range as expressed by progress (a number from 0-1)
@param [number]: Lower limit of range
@param [number]: Upper limit of range
@param [number]: The progress between lower and upper limits expressed 0-1
@return [number]: Value as calculated from progress within range (not limited within range)
*/
const getValueFromProgress = (from, to, progress) =>
(- progress * from) + (progress * to) + from;
/**
* Interpolate from set of values to another
*/
const slowInterpolate = (input, output, rangeLength, rangeEasing) => {
const finalIndex = rangeLength - 1;
// If input runs highest -> lowest, reverse both arrays
if (input[0] > input[finalIndex]) {
input.reverse();
output.reverse();
}
return (v) => {
// If value outside minimum range, quickly return
if (v <= input[0]) {
return output[0];
}
// If value outside maximum range, quickly return
if (v >= input[finalIndex]) {
return output[finalIndex];
}
let i = 1;
// Find index of range start
for (; i < rangeLength; i++) {
if (input[i] > v || i === finalIndex) {
break;
}
}
const progressInRange = getProgressFromValue(input[i - 1], input[i], v);
const easedProgress = (rangeEasing) ? rangeEasing[i - 1](progressInRange) : progressInRange;
return getValueFromProgress(output[i - 1], output[i], easedProgress);
};
};
const fastInterpolate = (minA, maxA, minB, maxB) => (v) =>
(((v - minA) * (maxB - minB)) / (maxA - minA)) + minB;
const interpolate = (input, output, rangeEasing) => {
const rangeLength = input.length;
return rangeLength !== 2
? slowInterpolate(input, output, rangeLength, rangeEasing)
: fastInterpolate(input[0], input[1], output[0], output[1])
};
console.log('int', interpolate([0,50,200],[0,0.5,1])(5))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment