Javascript – Logarithmic slider

javascriptlogarithmslider

I have a slider with values ranging from 0 to 100.

I want to map them to a range from 100 to 10,000,000.

I've seen some functions scattered around the net but they're all in C++.
I need it in Javascript.

Any ideas?

Best Solution

You can use a function like this:

``````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);

var scale = (maxv-minv) / (maxp-minp);

return Math.exp(minv + scale*(position-minp));
}
``````

The resulting values match a logarithmic scale:

``````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
``````

The reverse function would, with the same definitions for `minp`, `maxp`, `minv`, `maxv` and `scale`, calculate a slider position from a value like this:

``````function logposition(value) {
// set minv, ... like above
// ...
return (Math.log(value)-minv) / scale + minp;
}
``````

All together, wrapped in a class and as a functional code snippet, it would look like this:

``````// 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" />``````