UNPKG

@dominicstop/utils

Version:

Yet another event emitter written in typescript.

122 lines (121 loc) 4.12 kB
export function lerp(valueStart, valueEnd, percent) { let deltaRange = valueEnd - valueStart; let totalChange = deltaRange * percent; let interpolatedValue = valueStart + totalChange; return interpolatedValue; } ; /** * solve for `percent`, given: `valueStart`, `valueEnd`, `interpolatedValue` * * lerp formula, solve for `p` * ``` * iv = vs + p * (vs - ve) * iv - vs = p * (vs - ve) * (iv - vs) / (vs - ve) = p * ``` */ export function inverseLerp(valueStart, valueEnd, interpolatedValue) { const deltaChange = interpolatedValue - valueStart; const deltaRange = valueEnd - valueStart; const changePercent = deltaChange / deltaRange; return changePercent; } ; export function rangedLerpUsingInputValue(inputValue, inputValueStart, inputValueEnd, outputValueStart, outputValueEnd) { const inputValueAdj = inputValue - inputValueStart; const inputRangeDelta = inputValueEnd - inputValueStart; const progressRaw = inputValueAdj / inputRangeDelta; const progress = Number.isFinite(progressRaw) ? progressRaw : 0; return lerp( /* valueStart: */ outputValueStart, /* valueEnd : */ outputValueEnd, /* percent : */ progress); } ; export function rangedLerpUsingRelativePercent(relativePercent, inputValueStart, inputValueEnd, outputValueStart, outputValueEnd) { const rangeDelta = Math.abs(inputValueStart - inputValueEnd); const inputValue = rangeDelta * relativePercent; const percentRaw = inputValue / rangeDelta; const percent = Number.isFinite(percentRaw) ? percentRaw : 0; return lerp( /* valueStart: */ outputValueStart, /* valueEnd : */ outputValueEnd, /* percent : */ percent); } ; export function rangedLerpUsingArray(inputValue, rangeInput, rangeOutput, shouldClampMin = false, shouldClampMax = false) { if (rangeInput.length != rangeOutput.length || rangeInput.length <= 2) { return; } ; if (shouldClampMin && inputValue < rangeInput[0]) { return rangeInput[0]; } ; if (shouldClampMax && inputValue < rangeInput.slice(-1)[0]) { return rangeInput.pop(); } ; // A - Extrapolate Left if (inputValue < rangeInput[0]) { const rangeInputStart = rangeInput[0]; const rangeInputEnd = rangeInput[1]; const rangeOutputStart = rangeOutput[0]; const rangeOutputEnd = rangeOutput[1]; return rangedLerpUsingInputValue( /* inputValue: */ inputValue, /* inputValueStart: */ rangeInputEnd, /* inputValueEnd: */ rangeInputStart, /* outputValueStart: */ rangeOutputEnd, /* outputValueEnd: */ rangeOutputStart); } ; const [rangeStartIndex, rangeEndIndex] = (() => { const matchIndex = rangeInput.findIndex((currentValue, index) => { const nextValue = rangeInput[index + 1]; if (nextValue == null) { return false; } ; return inputValue >= currentValue && inputValue < nextValue; }); // B - Interpolate Between if (matchIndex != null) { return [matchIndex, matchIndex + 1]; } ; const lastIndex = rangeInput.length - 1; const secondToLastIndex = rangeInput.length - 2; // C - Extrapolate Right return [secondToLastIndex, lastIndex]; })(); const rangeInputStart = rangeInput[rangeStartIndex]; if (rangeInputStart == null) { return; } ; const rangeInputEnd = rangeInput[rangeEndIndex]; if (rangeInputEnd == null) { return; } ; const rangeOutputStart = rangeOutput[rangeStartIndex]; if (rangeOutputStart == null) { return; } ; const rangeOutputEnd = rangeOutput[rangeEndIndex]; if (rangeOutputEnd == null) { return; } ; return rangedLerpUsingInputValue( /* inputValue : */ inputValue, /* inputValueStart : */ rangeInputStart, /* inputValueEnd : */ rangeInputEnd, /* outputValueStart: */ rangeOutputStart, /* outputValueEnd : */ rangeOutputEnd); } ;