У меня есть ползунок со значениями от 0 до 100.
Я хочу отобразить их в диапазоне от 100 до 10 000 000.
Я видел некоторые функции, разбросанные по сети, но все они на С++. Мне нужно это в Javascript.
Любые идеи?
У меня есть ползунок со значениями от 0 до 100.
Я хочу отобразить их в диапазоне от 100 до 10 000 000.
Я видел некоторые функции, разбросанные по сети, но все они на С++. Мне нужно это в Javascript.
Любые идеи?
Вы можете использовать такую функцию:
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, но не могу найти ни одного, и затем я наткнулся на этот ответ,
И я создал это для Angular 2+ (демонстрация на 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;
}
};
Проблема с настоящим логарифмическим ползунком заключается в том, что на нижнем уровне несколько точек ползунка часто приводят к дублированию значений.
С точки зрения чисто пользовательского интерфейса, он также не обеспечивает очень интуитивно понятного вывода для пользовательского ввода.
Я думаю, что лучшим вариантом является использование "ступенчатого" преобразования с равномерным распределением.
Другими словами, мы указываем серию приращений, которые мы хотим использовать (например: 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
.
Примечание. Точки ползунка не должны превышать количество пикселей в ползунке.
Затем мы просто преобразуем наш вывод, используя алгоритм, описанный выше. Пример кода также выполняет некоторую работу, поэтому выходные данные всегда округляются для текущего интервала шага.