我有一个滑块,其值介于0到100之间。
我想将它们映射到100到10,000,000的范围。
我看到一些功能散布在网络上,但它们都是用C ++编写的。 我在Javascript中需要它。
有什么想法吗?
答案 0 :(得分:159)
您可以使用以下功能:
function logslider(position) {
// position will be between 0 and 100
var minp = 0;
var maxp = 100;
// The result should be between 100 an 10000000
var minv = Math.log(100);
var maxv = Math.log(10000000);
// calculate adjustment factor
var scale = (maxv-minv) / (maxp-minp);
return Math.exp(minv + scale*(position-minp));
}
结果值与对数刻度匹配:
js> logslider(0);
100.00000000000004
js> logslider(10);
316.22776601683825
js> logslider(20);
1000.0000000000007
js> logslider(40);
10000.00000000001
js> logslider(60);
100000.0000000002
js> logslider(100);
10000000.000000006
反向函数对minp
,maxp
,minv
,maxv
和scale
的定义相同,从值计算滑块位置像这样:
function logposition(value) {
// set minv, ... like above
// ...
return (Math.log(value)-minv) / scale + minp;
}
所有这些都包含在一个类中,作为一个功能代码片段,它看起来像这样:
// Generic class:
function LogSlider(options) {
options = options || {};
this.minpos = options.minpos || 0;
this.maxpos = options.maxpos || 100;
this.minlval = Math.log(options.minval || 1);
this.maxlval = Math.log(options.maxval || 100000);
this.scale = (this.maxlval - this.minlval) / (this.maxpos - this.minpos);
}
LogSlider.prototype = {
// Calculate value from a slider position
value: function(position) {
return Math.exp((position - this.minpos) * this.scale + this.minlval);
},
// Calculate slider position from a value
position: function(value) {
return this.minpos + (Math.log(value) - this.minlval) / this.scale;
}
};
// Usage:
var logsl = new LogSlider({maxpos: 20, minval: 100, maxval: 10000000});
$('#slider').on('change', function() {
var val = logsl.value(+$(this).val());
$('#value').val(val.toFixed(0));
});
$('#value').on('keyup', function() {
var pos = logsl.position(+$(this).val());
$('#slider').val(pos);
});
$('#value').val("1000").trigger("keyup");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Input value or use slider:
<input id="value" />
<input id="slider" type="range" min="0" max="20" />
答案 1 :(得分:9)
为了获得您想要的发行版,我认为您可以使用以下公式:
var value = Math.floor(-900 + 1000*Math.exp(i/10.857255959));
这是一个自包含的页面,它将打印您为0-100滑块获得的值,并已通过该公式:
<html><body><script>
for (var i = 0; i <= 100; i++) {
var value = Math.floor(-900 + 1000*Math.exp(i/10.857255959));
document.write(value + "<br>");
}
</script></body></html>
数字从100到10,000,000,在数学上看起来像生锈的眼睛看你想要的分布。 8 - )
答案 2 :(得分:9)
不完全回答这个问题,但对于感兴趣的人来说,最后一行的反向映射是
return (Math.log(value)-minv)/scale + min;
只是为了记录。
注意值必须> 0
答案 3 :(得分:1)
我一直在搜索对角线对角滑块,但找不到任何滑动块,然后我遇到了这个答案,
我已经为Angular 2+(Demo在Angular 6中)创建了它: WORKING DEMO
感谢 @sth ,以获取摘要:
function LogSlider(options) {
options = options || {};
this.minpos = options.minpos || 0;
this.maxpos = options.maxpos || 100;
this.minlval = Math.log(options.minval || 1);
this.maxlval = Math.log(options.maxval || 100000);
this.scale = (this.maxlval - this.minlval) / (this.maxpos - this.minpos);
}
LogSlider.prototype = {
// Calculate value from a slider position
value: function(position) {
return Math.exp((position - this.minpos) * this.scale + this.minlval);
},
// Calculate slider position from a value
position: function(value) {
return this.minpos + (Math.log(value) - this.minlval) / this.scale;
}
};
答案 4 :(得分:0)
对数滑块为真的问题是在低端,滑块上的多个点通常会导致值重复。
从纯UI的角度来看,它也不能为用户输入提供非常直观的输出。
我认为更好的选择是使用均匀分布的“阶梯式”变换。
换句话说,我们指定了要使用的一系列增量(例如:1、10、100、1000)。然后,根据定义的增量数将滑块分成相等的部分。当我们在不同部分中滑动时,滑块输出将以各自的增量递增。
在上面的示例中,我们定义了min
,max
和intervals
数组。
<ExpoStepSlider
intervals={[1, 2, 5, 10, 100, 1000]}
min={1}
max={50000}
/>
然后,我们必须找到滑块必须具有的离散值的数量,以使其根据定义的间隔分布正确地从最小值变为最大值。
let sliderPoints = Math.ceil(
(max - min) /
intervals.reduce((total, interval) => total + interval / intervals.length, 0)
);
在这种情况下,535
。
注意 :您的滑块点不得超过滑块中的像素数
最后,我们仅使用上述算法转换输出。该代码示例也做了一些工作,因此对于当前步进间隔,输出始终是四舍五入的。