I would like to create a function in plain JS that can increment or decrement by changing the increment or decrement value at each decade passage (which is my problem here)
For example:
0.1 -> 0.2 -> 0.3 -> 0.4 -> ... -> 1 -> 2 -> 3 -> ... -> 8 -> 9 -> 10 -> 20 -> 30 -> 40 -> ... -> 90 -> 100 -> 200 -> 300 -> etc.
or
0.8 -> 0.7 -> 0.6 ... -> 0.2 -> 0.1 -> 0.09 -> 0.08 -> 0.07 -> ... -> 0.02 -> 0.01 -> 0.009 -> 0.008 -> 0.007 -> etc.
Does someone have an idea on how to handle that?
CodePudding user response:
Look at the current value, then find where the value fits in with your range steps, add it to the step property.
function rangeFinder(ranges) {
const keys = Array.from(ranges)
keys.sort(function(a, b) {
return Number(a) - Number(b)
})
return function(val) {
let key = null
const len = keys.length
for (let i = 0; i < len; i ) {
if (key === null || keys[i] < val) {
key = Math.max(key, keys[i])
}
}
return key
}
}
const ranges = [
'.000001',
'.00001',
'.0001',
'.001',
'.01',
'.1',
'1',
'10',
'100',
'1000'
]
const input = document.querySelector('[type="number"]')
input.oninput = function() {
const value = Number(this.value)
const range = rangeFinder(ranges)(value)
input.setAttribute('step', range)
console.log(value, range, value range)
}
<input type="number" min="0.000000" max="10000" value="0.000000" step=".000001">
CodePudding user response:
I would use math to get the increment appropriate for the number.
The rounding issue that Barmar mentioned is taken care of by performing the addition, creating a string of the required precision (here only 1 because there is only 1 significant digit, but that would need to change if there were more), and then parsing it as a new float.
function getIncrement(num) {
let abs = Math.abs(num);
let inc = Math.pow(10, Math.floor(Math.log10(abs)));
if (abs === num) return inc;
return -inc;
}
let x = 0.1;
let out = [x];
while (x < 1000) {
x = parseFloat((x getIncrement(x)).toPrecision(1));
out.push(x);
}
console.log(out);