Normalizing or interpolating values in JavaScript/TypeScript
Pablo Garcia
Posted on December 13, 2023
These are three common normalizing functions I use in JavaScript when working with CSS animations/transitions, especially when playing with motion sensors.
Standard Normalization
This function scales a number so that it falls within a standard range of 0 to 1. This is the common meaning of "normalization" in data processing.
Commonly used in data processing and analysis to standardize different sets of data on a common scale, such as in machine learning feature scaling.
function normalize(
value: number,
minValue: number,
maxValue: number
): number {
if (maxValue === minValue) {
return value === minValue ? 1 : 0;
}
return (value - minValue) / (maxValue - minValue);
}
// Example Usage
console.log(normalize(15, 10, 20)); // 0.5
console.log(normalize(30, 20, 40)); // 0.5
Linear Interpolation
This function maps a number from one range to another. It's a form of linear interpolation.
Useful for scaling values, normalizing data to a different range, or converting between different measurement scales.
function linearInterpolation(
value: number,
originLowerBound: number,
originUpperBound: number,
targetLowerBound: number,
targetUpperBound: number
): number {
// Note: we should use the `normalize` function above
// const ratio = normalize(value, originLowerBound, originUpperBound)
const ratio =
(value - originLowerBound) / (originUpperBound - originLowerBound);
return ratio * (targetUpperBound - targetLowerBound) + targetLowerBound;
}
// Example Usage
const mappedValue = linearInterpolation(5, 0, 10, 0, 100);
console.log(mappedValue); // Should output 50
For example: [1,5] & [10,50] ranges.
- 1 outputs 10
- 2 outputs 20
- ...
Modular Arithmetic-Based Wrapping
This function ensures that a given value is wrapped within a specified numeric range. If the value exceeds the range, it wraps around within this range using modular arithmetic.
Ideal for cyclic or repeating ranges, like angles (think CSS transformations from 0 to 360 degrees), hours on a clock, or other periodic values.
function cyclicInterpolation(
value: number,
lowerBound: number,
upperBound: number
): number {
// adding 1 to include the upper bound in the range
const shiftedUpperBound = upperBound - lowerBound + 1;
const shiftedValue = value - lowerBound;
return (
lowerBound +
// adding parenthesis for emphasis
(((shiftedValue % shiftedUpperBound) + shiftedUpperBound) %
shiftedUpperBound)
);
}
// Example Usage
console.log(cyclicInterpolation(5, 3, 7)); // Outputs 5
console.log(cyclicInterpolation(6, 3, 7)); // Outputs 6
console.log(cyclicInterpolation(7, 3, 7)); // Outputs 7
console.log(cyclicInterpolation(8, 3, 7)); // Outputs 3 - restarts cycle
For example: [1,10]
- 1 outputs 1
- 9 outputs 9
- 10 outputs 10
- 11 outputs 1 - going back to the beginning
Posted on December 13, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.