Javascript / jQuery - 将一个数字范围映射到另一个数字范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10756313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:48:27  来源:igfitidea点击:

Javascript / jQuery - map a range of numbers to another range of numbers

javascriptjquery

提问by mheavers

In other programming languages such as processing, there is a function which allows you to convert a number that falls within a range of numbers into a number within a different range. What I want to do is convert the mouse's X coordinate into a range between, say, 0 and 15. So the browser's window dimensions, while different for every user, might be, say, 1394px wide, and the current X coordinate might be 563px, and I want to convert that to the range of 0 to 15.

在其他编程语言(例如处理)中,有一个函数可以将一个数字范围内的数字转换为不同范围内的数字。我想要做的是将鼠标的 X 坐标转换为介于 0 和 15 之间的范围。因此,浏览器的窗口尺寸虽然每个用户都不同,但可能是 1394px 宽,而当前的 X 坐标可能是 563px ,我想将其转换为 0 到 15 的范围。

I'm hoping to find a function of jquery and javascript that has this ability built in. I can figure out the math to do this by myself, but I'd rather do this in a more concise and dynamic way.

我希望能找到一个内置了这种能力的 jquery 和 javascript 函数。我可以自己算出数学来做到这一点,但我宁愿以更简洁和动态的方式来做到这一点。

I'm already capturing the screen dimensions and mouse dimensions with this code:

我已经使用以下代码捕获屏幕尺寸和鼠标尺寸:

var $window = $(window);
var $document = $(document);


$document.ready(function() {
    var mouseX, mouseY; //capture current mouse coordinates
    var screenW, screenH; //capture the current width and height of the window
    var maxMove = 10;
    windowSize();

    $document.mousemove( function(e) {
        mouseX = e.pageX; 
        mouseY = e.pageY;

    });

    $window.resize(function() {
        windowSize();
    });

    function windowSize(){
        screenW = $window.width();
        screenH = $window.height();
    }

});

Thanks for any help you can provide.

感谢您的任何帮助,您可以提供。

回答by August Miller

You can implement this as a pure Javascript function:

您可以将其实现为纯 Javascript 函数:

const scale = (num, in_min, in_max, out_min, out_max) => {
  return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Use the function, like this:

使用该函数,如下所示:

const num = 5;
console.log(scale(num, 0, 10, -50, 50)); // 0
console.log(scale(num, -20, 0, -100, 100)); // 150

I'm using scalefor the function name, because mapis frequently associated with iterating over arrays and objects.

我使用scale函数名,因为map它经常与迭代数组和对象相关联。



Below is the original answer. I can no longer recommend modification of native prototypes.

以下是原答案。我不能再推荐修改原生原型。

If you'd like to have access to this in the Number class, you can add it as…

如果您想在 Number 类中访问它,您可以将其添加为...

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;
}

…wherein you specify in the "minimum" and "maximum" values of expected input and the "minimum" and "maximum" values to be output. This canand willproduce out-of-range values if the incoming value itself is not between in_minand in_max.

...其中您在预期输入的“最小值”和“最大值”以及要输出的“最小值”和“最大值”值中指定。如果传入的值本身不在和之间,这可以并且将会产生超出范围的值。in_minin_max

Use it like this:

像这样使用它:

var num = 5;
console.log(num.map(0, 10, -50, 50)); // 0
console.log(num.map(-20, 0, -100, 100)); // 150

Edit: I've made this available as a Gist, so you don't have to look this up, in the future.

编辑:我已将此作为 Gist 提供,因此您将来不必查找此内容。

回答by Gabriele Petrioli

If your range always starts from 0 then all you have to do is

如果您的范围总是从 0 开始,那么您所要做的就是

mouseValue * range.max / screen.max


A more involved any-range to any-range conversion would require

更复杂的任意范围到任意范围的转换需要

function convertToRange(value, srcRange, dstRange){
  // value is outside source range return
  if (value < srcRange[0] || value > srcRange[1]){
    return NaN; 
  }

  var srcMax = srcRange[1] - srcRange[0],
      dstMax = dstRange[1] - dstRange[0],
      adjValue = value - srcRange[0];

  return (adjValue * dstMax / srcMax) + dstRange[0];

}

Use like convertToRange(20,[10,50],[5,10]);

使用喜欢 convertToRange(20,[10,50],[5,10]);

回答by Alias Robert Cummins

For a general purpose mapping function, which is what the OP asked for, go here:

对于 OP 要求的通用映射函数,请访问此处:

http://rosettacode.org/wiki/Map_range#JavaScript

http://rosettacode.org/wiki/Map_range#JavaScript

回答by Death

function proportion(value,max,minrange,maxrange) {
    return Math.round(((max-value)/(max))*(maxrange-minrange))+minrange;
}

In your case, use this as proportion(screencoord,screensize,0,15)

在您的情况下,将其用作 proportion(screencoord,screensize,0,15)

You'd also presumably want to get the Client size, not the screen size, as the Screen size refers to the maximum dimensions of the monitor, and not all users maximise their screen.

您可能还想获得客户端尺寸,而不是屏幕尺寸,因为屏幕尺寸是指显示器的最大尺寸,而不是所有用户都最大化其屏幕。

回答by Jerome Cance

Let's say you have 6 variables :

假设您有 6 个变量:

  • minRange (0 in your example)
  • maxRange (15 in your example)
  • x
  • y
  • browserWidth
  • browserHeight
  • minRange(在您的示例中为 0)
  • maxRange(在您的示例中为 15)
  • X
  • 浏览器宽度
  • 浏览器高度

To have the range :

要有范围:

interval = maxRange - minRange;
rangeX = interval * x / browserWidth + minRange
rangeY = interval * y / browserHeight + minRange

回答by Alex Turpin

This is simple math.

这是简单的数学。

var screenWidth = $(window).width();
var mousePosition = e.pageX;
var max = 15;
var value = (mousePosition / screenWidth) * max;

Note that this can return a decimal number; if you don't want that, you can use Math.roundon the result.

请注意,这可以返回一个十进制数;如果你不想那样,你可以Math.round在结果上使用。

Live example

活生生的例子

回答by hot_barbara

I've taken August Miller's idea and added limits to them (value can't go outside the range of in_min and in_max and if it does it returns out_min and out_max respectively) and minified it for those who want a copy paste function for their scripts:

我采用了 August Miller 的想法并为它们添加了限制(值不能超出 in_min 和 in_max 的范围,如果超出,则分别返回 out_min 和 out_max)并为那些想要复制粘贴功能的脚本缩小它:

function map(n,i,o,r,t){return i>o?i>n?(n-i)*(t-r)/(o-i)+r:r:o>i?o>n?(n-i)*(t-r)/(o-i)+r:t:void 0}

function map(n,i,o,r,t){return i>o?i>n?(n-i)*(t-r)/(o-i)+r:r:o>i?o>n?(n-i)*(t-r)/(o-i)+r:t:void 0}

params are like map(value, in_min, in_max, out_in, out_max)

参数就像 map(value, in_min, in_max, out_in, out_max)

回答by GAME DEV

well its simple math. well you have two ranges range1 = [a1,a2]and range2 = [b1,b2]and you want to map a value sin range one to a value tin range two. so this is the formula. t = b1 + (s-a1)*(b2-b1)/(a2-a1)in js it will be.

以及它的简单数学。好吧,您有两个范围range1 = [a1,a2]range2 = [b1,b2]并且您想将s范围一中的值映射到t范围二中的值。所以这就是公式。 t = b1 + (s-a1)*(b2-b1)/(a2-a1)在js中它将是。

var mapRange = function(from, to, s) {
  return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);
};

var range = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (var i = 0; i < range.length; i++) {
  range[i] = mapRange([0, 10], [-1, 0], range[i]);
}

console.log(range);