Home

Awesome

Math.clamp

ECMAScript proposal and reference implementation for Math.clamp.

Author: Richie Bendall

Champion: None

Stage: 0

Overview and motivation

A clamping function constrains a value between an upper and lower bound.

Our primary motivation is its usefulness and popularity in existing projects where it is often defined for the sake of readability. A common use is for animations and interactive content. For example, it helps to keep objects in-bounds during user-controlled movement by restricting the coordinates that it can move to (see the p5.js demo for its constrain function). Projects tend to define a function that looks like clamp(number, min, max), either through:

function clamp(number, minimum, maximum) {
	if (number < minimum) {
		return minimum;
	}

	if (number > maximum) {
		return maximum;
	}

	return number;
}
function clamp(number, minimum, maximum) {
	return Math.min(Math.max(number, minimum), maximum);
}

Each of those examples require unnecessary boilerplate and are error-prone. For example, a developer only has to mistype a single operator or mix up a single variable name for the function to break. They also disregard the potential undefined behaviour that can occur when minimum is larger than maximum, or when only min or max is specified.

We name it the function clamp, like how it is in other programming languages...

...and userland implementations:

Another motivation is to bring parity with the CSS function of the same name, although it will have a different parameter order because of the slightly different use cases in each context (also see the previous discussion on the order of options for CSS clamp.

Recognizing the usefulness and improved readability of only specifying either a min or max (i.e. Math.min(number, 5) vs Math.clamp(number, undefined, 5)), we consider also allowing null or undefined as values for min and max to semantically mean "no upper/lower bound". We consider this as opposed to Math.clampMin and Math.clampMax, or an option bag, to remain conventional to the language.

Examples

The proposed API allows a developer to clamp numbers like:

Math.clamp(5, 0, 10);
//=> 5

Math.clamp(-5, 0, 10);
//=> 0

Math.clamp(15, 0, 10);
//=> 10

It handles a larger minimum than maximum number, like how the CSS clamp() function does.

// Minimum number is larger than maximum value
Math.clamp(10, 5, 0);
//=> 10

It supports null/undefined/-Infinity/Infinity to specify when there is no upper or lower bound:

Math.clamp(5, 0, null);
//=> 5

Math.clamp(5, undefined, 10);
//=> 5

Specification

Implementations

Acknowledgements

Specification and reference implementation inspired by: