Skip to content

Instantly share code, notes, and snippets.

@remy
Last active March 4, 2024 22:48
Show Gist options
  • Save remy/5213884 to your computer and use it in GitHub Desktop.
Save remy/5213884 to your computer and use it in GitHub Desktop.
function map(x, in_min, in_max, out_min, out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Re-maps a number from one range to another. That is, a value of fromLow would get mapped to toLow, a value of fromHigh to toHigh, values in-between to values in-between, etc.

Directly ported/pinched from Arduino reference.

This simple example converts the gamma range from the device orientation event from a floating point between -90 and +90 to an unsigned int (via | 0) between -5 and +5:

window.addEventListener('deviceorientation', function (event) {
  var g = map(event.gamma, -90, 90, -5, 5) | 0;
  el.innerHTML = ['\ngamma', g].join(' ');
}, false);
@latentflip
Copy link

One of my favourite utlities in d3 are scales, which do a similar thing.

Here is an example of a linear scale that works like a linear scale in d3 (sorry for the coffeescript just ripped this out of a project of my own).

linearScale = ->
  domain = [0,1]
  range = [0,1]


  fn = (value) ->
    range[0] + (value - domain[0]) * (range[1] - range[0])/(domain[1] - domain[0])


  fn.domain = (newDomain) ->
    if !newDomain
      return domain
    else
      domain = newDomain
      fn
  fn.range = (newRange) ->
    if !newRange
      range
    else
      range = newRange
      fn
  return fn

This creates a linear scale, but in d3 you can create logarithmic scales and so on. D3 also does some really neat stuff like letting you map an input number to an output color range.

What's nice about this approach is it generates a mapping function for you, which you can then just call with the input value and get a new output value. It also means you can dynamically change the input domain or output range at runtime. This is better explained with an example:

angleMap = linearScale()
                    .domain([-90,90])  //input domain
                    .range([-5,5])        //output range

angleMap(-90)  //=> -5
angleMap(45)   //=> 2.5

angleMap.range([-500, 500])
angleMap(90) //=> 500

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