Skip to content

Instantly share code, notes, and snippets.

@xposedbones
Last active June 17, 2024 02:30
Show Gist options
  • Save xposedbones/75ebaef3c10060a3ee3b246166caab56 to your computer and use it in GitHub Desktop.
Save xposedbones/75ebaef3c10060a3ee3b246166caab56 to your computer and use it in GitHub Desktop.
Javascript Map range of number to another range
Number.prototype.map = function (in_min, in_max, out_min, out_max) {
return (this - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
export function clamp(input: number, min: number, max: number): number {
return input < min ? min : input > max ? max : input;
}
export function map(current: number, in_min: number, in_max: number, out_min: number, out_max: number): number {
const mapped: number = ((current - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;
return clamp(mapped, out_min, out_max);
}
@enijar
Copy link

enijar commented Jun 23, 2019

Here's a one-liner, for anyone interested.

const map = (value, x1, y1, x2, y2) => (value - x1) * (y2 - x2) / (y1 - x1) + x2;

@paul-asvb
Copy link

Thanks

@ronerlih
Copy link

I use this snippet a lot. thanks!

@xposedbones
Copy link
Author

I use this snippet a lot. thanks!

Glad you like it!

@SergeyKhval
Copy link

@enijar thanks for this, exactly what I was looking for

@mekb-turtle
Copy link

mekb-turtle commented Aug 24, 2021

add if(out_min==out_max&&!isNaN(this))return out_min; to stop from returning NaN if out min/max is same

@marcusx2
Copy link

marcusx2 commented Nov 2, 2021

For float values at least, this method doesn't work. It can actually go slightly above. This is the correct function to deal with floats

(Number as any).prototype.map = function (in_min, in_max, out_min, out_max) {
	let val = (this - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
	if (val < out_min) val = out_min;
	else if (val > out_max) val = out_max;
	return val;
}

@xposedbones
Copy link
Author

For float values at least, this method doesn't work. It can actually go slightly above. This is the correct function to deal with floats

(Number as any).prototype.map = function (in_min, in_max, out_min, out_max) {
	let val = (this - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
	if (val < out_min) val = out_min;
	else if (val > out_max) val = out_max;
	return val;
}

@marcusx2 Since you added (Number as any) I updated the snippet and add a typescript version to reflect what I currently use in production

@nwazuo
Copy link

nwazuo commented Jun 27, 2022

If you use GSAP, it has this as one of its utility methods as gsap.utils.mapRange. I haven't quite tested out how it deals with cases like floats. Also, I like that GSAP's mapRange has a handy feature that makes it return a function that 'remembers' the in_min, in_max, etc., values so that you can pass in any number input to repeat calculations with the same ranges.

@mekb-turtle
Copy link

simpler version:

const lerp = (a, b, t) => (b-a)*t+a;
const unlerp = (a, b, t) => (t-a)/(b-a);
const map = (a1, b1, a2, b2, t) => lerp(a2, b2, unlerp(a1, b1, t));

@LeoniePhiline
Copy link

@mekb-turtle What does lerp mean?

@mekb-turtle
Copy link

@mekb-turtle What does lerp mean?

Linear Interpolation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment