Curseur logarithmique

J'ai un curseur avec des valeurs allant de 0 à 100.

Je veux les mapper à une plage de 100 à 10 000 000.

J'ai vu quelques fonctions dispersées sur le net mais elles sont toutes en C++. J'en ai besoin en Javascript.

Des idées?

64
demandé sur Flip 2009-05-11 02:16:51

4 réponses

Vous pouvez utiliser une fonction comme celle-ci:

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

Les valeurs résultantes correspondent à une échelle logarithmique:

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

La fonction d'inversion, avec les mêmes définitions pour minp, maxp, minv, maxv et scale, calculer la position du curseur à partir d'une valeur comme ceci:

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


Tous ensemble, enveloppés dans une classe et en tant qu'extrait de code fonctionnel, cela ressemblerait à ceci:

// 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" />
150
répondu sth 2014-09-30 11:09:52

Pour obtenir la distribution que vous voulez, je pense que vous pouvez utiliser cette formule:

var value = Math.floor(-900 + 1000*Math.exp(i/10.857255959));

Voici une page autonome qui imprimera les valeurs que vous obtiendrez pour votre curseur 0-100, après les avoir passées à travers cette formule:

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

Les chiffres vont de 100 à 10 000 000 dans ce qui semble à mon œil mathématiquement rouillé être la distribution que vous voulez. 8-)

9
répondu RichieHindle 2009-05-10 22:31:17

Ne répond pas tout à fait à la question, mais pour les personnes intéressées, la cartographie inverse de la dernière ligne est

return (Math.log(value)-minv)/scale + min;

Juste pour documenter.

NOTE la valeur doit être > 0.

8
répondu siliconeagle 2011-11-19 16:38:09

Je cherchais curseur logarithmique pour Angular mais je n'en trouve pas et puis je suis tombé sur cette réponse,

Et j'ai créé cela pour Angular 2+ (La démo est en Angular 6) : démo de travail

Merci à @ sth , pour l'extrait de code:

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
répondu Vivek Doshi 2018-08-03 11:32:15