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

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

本文关键字:范围 数字 一个 映射 另一个 jQuery Javascript      更新时间:2023-09-26

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

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

我已经用这段代码捕获了屏幕尺寸和鼠标尺寸:

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

感谢您提供的任何帮助。

你可以把它实现为一个纯的Javascript函数:

function scale (number, inMin, inMax, outMin, outMax) {
    return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
}

使用该函数,如下所示:

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

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

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

mouseValue * range.max / screen.max

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

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

convertToRange(20,[10,50],[5,10]);一样使用

对于通用映射函数,这是OP所要求的,请转到此处:

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

这是简单的数学。

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

请注意,这可以返回一个十进制数;如果您不希望这样做,则可以对结果使用 Math.round

现场示例

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

在您的情况下,请使用此proportion(screencoord,screensize,0,15)

您可能还希望获取客户端大小,而不是屏幕大小,因为屏幕大小是指显示器的最大尺寸,并且并非所有用户都会最大化其屏幕。

假设你有6个变量:

  • 最小范围(在您的示例中为 0)
  • 最大范围(示例中为 15)
  • x
  • y
  • 浏览器宽度
  • 浏览器高度

要有范围:

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

它简单的数学。好吧,您有两个范围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);
Floats应该

始终计算。

function scale(
    srcNum: number,
    src: [start: number, end: number],
    dst: [start: number, end: number]
): number {
    return ((srcNum - src[0]) * (dst[1] - dst[0])) / (src[1] - src[0]) + dst[0];
}
scale(1, [0, 10], [0, 255]);   // 25.5
scale(1.5, [0, 10], [0, 255]); // 38.25
scale(2, [0, 10], [0, 255]);   // 51

Integers,一个有效的方法是创建一个映射,所以不需要更多的计算。但这实际上取决于src范围的大小。对于大范围scale(...)应该更有效。

function createScale(
    src: [start: number, end: number],
    dst: [start: number, end: number]
): Record<number, number> {
    const map: Record<number, number> = {};
    for (let i = src[0]; i <= src[1]; i++) {
        map[i] = ((i - src[0]) * (dst[1] - dst[0])) / (src[1] - src[0]) + dst[0];
    }
    return map;
}
createScale([0, 10], [0, 255]);
// {
//     "1": 25.5,
//     "2": 51,
//     "3": 76.5,
//     "4": 102,
//     "5": 127.5,
//     "6": 153,
//     "7": 178.5,
//     "8": 204,
//     "9": 229.5,
//     "10": 255
// }

我采用了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}

参数类似于map(value,in_min,in_max,out_in,out_max)