在两个数字

时间:2015-05-15 13:45:47

标签: javascript

所以我一直在努力重新制作这里找到的滑块https://www.skylight.io/(向下滚动以查找价格滑块)。 到目前为止,我已经设法创建了类似的东西,但有些数字是硬编码的,这使得它很难改变而且不是很容易重复使用。 我一直在研究,我想我需要一起使用Math.log()和Math.exp()来实现类似上面的链接,但我不确定。

这是迄今为止我所拥有的一个小问题https://jsfiddle.net/7wrvpb34/

我觉得这个问题的数学部分让我停下来,所以任何帮助都会非常感激。

以下Javascript代码:

var slider = document.getElementById("slider")
var sliderFill = document.getElementById("slider-fill")
var knob = document.getElementById("knob")

var mouseDown;
var mousePos = {x:0};
var knobPosition;

var minPrice = 20;
var price = 0;
var minRequests = 50;
var requests = 50 + ",000";

var incrementSpeed = 2;
var incrementModifier = 20;
var incrementValue = 1;

var minMillionCount = 1;
var millionCount = 1;

var previousRequestAmount = 0;

document.getElementById("price").innerHTML = price;
document.getElementById("requests").innerHTML = requests;

highlightTable(1);

document.addEventListener('mousemove', function(e) {
    if(mouseDown) {
        updateSlider(e);
    }
})

function updateSlider(event) {
    mousePos.x = event.clientX - slider.getBoundingClientRect().left;
    mousePos.x -= knob.offsetWidth / 2;

    console.log(mousePos.x);

    if(mousePos.x < 0) {
        knob.style.left = "0px";
        sliderFill.style.width = "0px";
        price = 0;
        requests = 50 + ",000";
        document.getElementById("price").innerHTML = price;
        document.getElementById("requests").innerHTML = requests;
        return
    }
    if(mousePos.x > slider.offsetWidth - 20) {
        return
    }
    sliderFill.style.width = mousePos.x +  10 + "px";
    knob.style.left = mousePos.x + "px";
    //Increase requests by using X position of mouse
    incrementSpeed = mousePos.x / incrementModifier;
    requests = minRequests + (mousePos.x * incrementSpeed);
    //Round to nearest 1
    requests = Math.round(requests / incrementValue) * incrementValue;
    if (requests >= 1000){
        var m = requests/ 1000;
        m = Math.round(m / 1) * 1;
        //Problem, lower the modifier depending on requests
        incrementModifier = 20 * 0.95;
        document.getElementById("requests").innerHTML = m + " million";
        //Adjust Prices
        if(( requests >= 1000) && (requests < 10000)) {
            var numOfMillions = requests / 100;
            //Round to closest 10.
            //10 * number of millions
            var rounded = Math.round(numOfMillions / 10) * 10;
            price = minPrice + rounded;
            highlightTable(3);
        }
        //Adjust Prices
        if(requests >= 10000) {
            var numOfMillions = requests / 1000;
            var rounded = Math.round(numOfMillions / 1) * 1;
            var basePrice = minPrice * 6;
            price = basePrice + rounded;
            highlightTable(4);
        }
    } else {
        incrementModifier = 20;
        document.getElementById("requests").innerHTML = requests + ",000"
        if(requests < 100) {
            highlightTable(1);
            price = 0;
        } else {
            highlightTable(2);
            price = 20;
        }
    }
    previousRequestAmount = requests;
    document.getElementById("price").innerHTML = price;
}

knob.addEventListener('mousedown', function() {
    mouseDown = true;
});

document.addEventListener('mouseup', function() {
    mouseDown = false;
});


function highlightTable(rowNum) {
    var table = document.getElementById("payment-table")
    for(var i = 0; i < table.rows.length; ++i) {
        var row = table.rows[i]
        if(i == rowNum) {
            row.style.background = "grey"
        } else {
            row.style.background = "white";
        }

    }
}

感谢您的时间。

2 个答案:

答案 0 :(得分:0)

如果您希望它可以重复使用,则需要创建一个数学函数,将结果分配给请求数。我会给你一个非常简单的例子。

如果您想要1,10,100,100,10000等的不同结果

var d = Math.log10(requests);

if(d<1){
 doSomething();
}else if(d<2){
 doSomethingElse();
} //etc

这样,如果您想更改创建特定结果的特定值,您只需更改该功能。

这仅适用于您的请求层次遵循数学函数的情况,如果您不需要对其进行硬编码。

但是,如果说他们不遵循数学函数,但您知道如何根据值更改它们,那么您可以这样做。

var changingValue = 4;

if(requests < 400*changingValue){
 doSomthing();
}else if(requests <= 400*changingValue*changingValue){
 doSomethingElse();
}else{// the requests is greater than any of the above
 doTheOtherThing();
}

编辑:

对于第二个,您需要确保每个条件从上到下始终大于另一个条件。

答案 1 :(得分:0)

“越来越多”的描述与任意数量的功能相匹配。我假设你也希望它是连续,因为你已经有了一个不连续的解决方案。

TL; DR

使用指数函数。

通用方法

假设iminimax是滑块的最小值和最大值(输入为i),ominomax是最小值和最大值要显示的值,我能想到的最简单的事情是基于输入值的乘法:

f(x)
{
    return omin + (omax - omin) * g((x - imin) / (imax - imin));
}

如果0g会传递给x == imin1会传递x == imaxr的返回值g(y)应为

r == 0    for y == 0
r == 1    for y == 1
0 < r < y for 0 < y < 1

我能想到的最简单的函数是指数函数,指数&gt; 1.
指数为1将是线性函数 指数为2将使滑块的中间显示最大价格的四分之一而不是它的一半 但是你真的需要根据你的需求自己找到那个指数。