Domanda

Ho uno slider con valori che vanno da 0 a 100.

Voglio mapparli su un intervallo compreso tra 100 e 10.000.000.

Ho visto alcune funzioni sparse in rete ma sono tutte in C++.Mi serve in Javascript.

Qualche idea?

È stato utile?

Soluzione

È possibile utilizzare una funzione come questa:

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

I valori ottenuti corrispondono a una scala logaritmica:

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 funzione inversa avrebbe, con le stesse definizioni di minp, maxp, minv, maxv e scale, calcolare una posizione cursore da un valore così:

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

Tutti insieme, avvolto in una classe e come frammento di codice funzionale, sarebbe simile a questa:

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

Altri suggerimenti

Per ottenere la distribuzione che si desidera, penso che si può usare questa formula:

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

Ecco una pagina self-contained che stamperà i valori che si ottengono per il vostro 0-100 cursore, avendoli passò attraverso la formula:

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

I numeri vanno da 100 a 10 milioni in quello che sembra al mio occhio matematicamente-ruggine ad essere la distribuzione che si desidera. 8 -)

Non risponde del tutto alla domanda, ma per le persone interessate, la mappatura inversa dell'ultima riga è

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

solo per documentare.

NOTA il valore deve essere > 0.

ero alla ricerca di dispositivo di scorrimento logaritmica per angolare , ma non riesco a trovare alcuna e poi mi sono imbattuto in questa risposta,

E ho creato che per angolare 2+ (Demo è in angolare 6): LAVORO DEMO

Grazie alla @sth , per il frammento:

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

Il problema con un vero cursore logaritmico è che all'estremità inferiore più punti sul cursore spesso daranno come risultato valori duplicati.

Dal punto di vista puramente dell'interfaccia utente, inoltre, non fornisce un output molto intuitivo per l'input degli utenti.

Penso che un'opzione migliore sia quella di utilizzare una trasformazione "a gradini" con distribuzione uniforme.

enter image description here

In altre parole, specifichiamo una serie di incrementi che vogliamo utilizzare (es:1, 10, 100, 1000).Quindi dividiamo il cursore in parti uguali in base al numero di incrementi che abbiamo definito.Quando scorriamo attraverso le nostre diverse sezioni, l'output del cursore aumenterà del rispettivo incremento.

DIMOSTRAZIONE FUNZIONANTE

CODICE REAGIRE

Nell'esempio sopra, definiamo our min, max & intervals vettore.

<ExpoStepSlider
  intervals={[1, 2, 5, 10, 100, 1000]}
  min={1}
  max={50000}
/>

Dobbiamo quindi trovare il numero di valori discreti che il nostro dispositivo di scorrimento deve avere in modo che vada correttamente dal minimo al massimo in base alle nostre distribuzioni di intervalli definite.

let sliderPoints = Math.ceil(
  (max - min) / 
  intervals.reduce((total, interval) => total + interval / intervals.length, 0)
);

In questo caso 535.

Nota:I punti del dispositivo di scorrimento non devono superare il numero di pixel nel dispositivo di scorrimento

Infine, trasformiamo semplicemente il nostro output utilizzando l'algoritmo descritto sopra.Anche l'esempio di codice esegue alcune operazioni, quindi l'output è sempre rotondo per l'intervallo del passaggio corrente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top