Логарифмический регулятор
У меня есть ползунок со значениями от 0 до 100.
Я хочу сопоставить их в диапазоне от 100 до 10 000 000.
Я видел некоторые функции, разбросанные по сети, но все они в C++. Мне это нужно в Javascript.
какие идеи?
4 ответа:
вы можете использовать такую функцию:
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" />
чтобы получить распределение, которое вы хотите, я думаю, вы можете использовать эту формулу:
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-)
Не совсем отвечая на вопрос, но для заинтересованных людей обратное отображение последней строки
return (Math.log(value)-minv)/scale + min;
просто документ.
Примечание значение должно быть > 0.
искал логарифмический ползунок для углового но не могу найти, а потом я наткнулся на этот ответ ,
и я создал это для Angular 2+ (демо находится в Angular 6): РАБОЧАЯ ДЕМОНСТРАЦИЯ
спасибо @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; } };