Created
May 19, 2018 02:19
-
-
Save jossmac/06305dc1c1712235325cec3caacd6f62 to your computer and use it in GitHub Desktop.
The best parts of https://github.com/Popmotion/popmotion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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