Ich habe einen Schieberegler mit Werten von 0 bis 100.
Ich möchte sie einem Bereich von 100 bis 10.000.000 zuordnen.
Ich habe einige Funktionen im Netz verstreut gesehen, aber sie sind alle in C++. Ich brauche es in Javascript.
Irgendwelche Ideen?
etw
Sie können eine Funktion wie diese verwenden:
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));
}
Die resultierenden Werte entsprechen einer logarithmischen Skala:
Die umgekehrte Funktion würde mit den gleichen Definitionen für minp, maxp, minv, maxv und scaleberechnen Sie eine Schiebereglerposition aus einem Wert wie diesem:
function logposition(value) {
// set minv, ... like above
// ...
return (Math.log(value)-minv) / scale + minp;
}
Alles zusammen, verpackt in eine Klasse und als funktionales Code-Snippet, würde es so aussehen:
// 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" />
Besteht die Möglichkeit, dass Sie die entgegengesetzte Funktion haben? Geben Sie anhand des Protokollwerts aus, an welcher Position sich der Schieberegler befindet.
– GeekyMonkey
9. März 2011 um 16:21 Uhr
Ist das nicht ein Exponentialschieber? Gibt es eine Möglichkeit, die Kurve so umzukehren, dass sie logarithmisch ist? Damit der Wert schnell steigt und zum Ende hin langsamer wird?
– Nick Hooked
2. März 2017 um 10:53 Uhr
@NickH: Hängt davon ab, wie man es betrachtet. Wenn die Schiebereglerposition derzeit nach oben geht, steigt der zugehörige Wert immer schneller an, also aus dieser Perspektive ist es exponentiell. Wenn Sie es umgekehrt brauchen, wechseln Sie value und position um den gegenteiligen Effekt zu erzielen.
– etw
2. März 2017 um 23:17 Uhr
@sth Danke, ich werde immer mit Exponential und Logarithmus verwechselt. Gibt es eine Möglichkeit, die Kurve in Ihrer Lösung weniger schnell ansteigen zu lassen (linearer, aber immer noch exponentiell)? Bei einer Eingabe von 50 liegt der Wert irgendwo um 550.
– Nick Hooked
3. März 2017 um 9:28 Uhr
Um die gewünschte Verteilung zu erhalten, können Sie meiner Meinung nach diese Formel verwenden:
var value = Math.floor(-900 + 1000*Math.exp(i/10.857255959));
Hier ist eine eigenständige Seite, die die Werte druckt, die Sie für Ihren 0-100-Schieberegler erhalten, nachdem Sie sie durch diese Formel geleitet haben:
<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>
Die Zahlen reichen von 100 bis 10.000.000, was für mein mathematisch rostiges Auge die gewünschte Verteilung zu sein scheint. 😎
Begonnen mit Math.exp(i) und von Hand angepasst, bis die Zahlen passen. Mein Mathe-Fu ist schwach, aber ich kann für England binär hacken. 😎
– Richie Hindle
10. Mai 2009 um 22:47 Uhr
Beantwortet die Frage nicht ganz, aber für Interessierte ist die umgekehrte Zuordnung der letzten Zeile
return (Math.log(value)-minv)/scale + min;
nur um zu dokumentieren.
HINWEIS: Der Wert muss > 0 sein.
NSjonas
Das Problem mit einem echten logarithmischen Schieberegler liegt am unteren Ende, mehrere Punkte auf dem Schieberegler führen wahrscheinlich zu doppelten Werten.
Aus reiner UI-Perspektive bietet es auch keine sehr intuitive Ausgabe für die Benutzereingabe.
Ich denke, eine bessere Option ist die Verwendung einer “gestuften” Transformation mit gleichmäßiger Verteilung.
Mit anderen Worten, wir geben eine Reihe von Inkrementen an, die wir verwenden möchten (z. B.: 1, 10, 100, 1000). Dann teilen wir den Schieberegler in gleiche Teile auf, basierend auf der Anzahl der von uns definierten Inkremente. Wenn wir durch unsere verschiedenen Abschnitte gleiten, erhöht sich die Schiebereglerausgabe um die jeweilige Schrittweite.
Wir müssen dann die Anzahl der diskreten Werte finden, die unser Schieberegler haben muss, damit er basierend auf unseren definierten Intervallverteilungen richtig vom Minimum zum Maximum geht.
let sliderPoints = Math.ceil(
(max - min) /
intervals.reduce((total, interval) => total + interval / intervals.length, 0)
);
In diesem Fall 535.
Notiz: Ihre Slider-Punkte sollten die Anzahl der Pixel im Slider nicht überschreiten
Schließlich transformieren wir einfach unsere Ausgabe mit dem oben beschriebenen Algorithmus. Das Codebeispiel leistet auch einige Arbeit, sodass die Ausgabe für das aktuelle Schrittintervall immer rund ist.
Ich suchte Logarithmischer Schieberegler für Angular aber ich kann keine finden und dann bin ich auf diese Antwort gestoßen,
Und das habe ich für Angular 2+ erstellt (Demo ist in Angular 6): FUNKTIONIERENDE DEMO
Dank an @etwfür Ausschnitt :
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;
}
};
POW()-Funktion
Hier ist eine etwas andere Einstellung mit einer pow()-Funktion. Dies ermöglicht das Einstellen einer “schrägen” Kurve, die die Verteilung der Eingangs- <-> Ausgangskurve bestimmt. Eine andere umgestaltete Version ermöglicht das Einstellen des Schiebereglers von der logarithmischen (exponentiellen) Eingabe.
$(document).ready(function() {
$('#test').change(function() {
this.value = parseFloat(this.value).toFixed(2);
widthSliderCurve = this.value;
});
});
var widthSliderCurve = 0.42; // between -1 and 1 - governs the way the range is skewed
widthSlider.oninput = function() {
var thisSlider = document.getElementById("widthSlider");
var curve = Math.pow(10, widthSliderCurve); // convert linear scale into lograthimic exponent for other pow function
var originalMin = 1.0; // these are set in the slider defintion in HTML make sure they match!
var originalMax = 200.0; // these are set in the slider defintion in HTML
var mappedOutputMin = 0.05; // this is the desired output min
var mappedOutputMax = 10; // this is the desired output max
var originalRange = originalMax - originalMin;
var newRange = mappedOutputMax - mappedOutputMin;
var zeroRefCurVal = thisSlider.value - originalMin; // zero referenced
var normalizedCurVal = zeroRefCurVal / originalRange; // normalized to 0-1 output
var rangedValue = ((Math.pow(normalizedCurVal, curve) * newRange) + mappedOutputMin).toFixed(2);
var outbox = document.getElementById("wSliderOutput");
outbox.innerHTML = rangedValue;
//paper.tool.LineWidth = rangedValue;
};
let setLogSlider = function(value, widthSliderCurve, sliderType, outputName) {
/*** make sure constants match the oninput function values ***/
var curve = Math.pow(10, widthSliderCurve);
var originalMin = 1.0; // these are set in the slider defintion in HTML make sure they match!
var originalMax = 200.0; // these are set in the slider defintion in HTML
var mappedOutputMin = 0.05; // this is the desired output min
var mappedOutputMax = 10; // this is the desired output max
var originalRange = originalMax - originalMin;
var newRange = mappedOutputMax - mappedOutputMin;
var logToLinear = Math.pow((value - mappedOutputMin) / newRange, 1 / curve) * originalRange + originalMin;
console.log("logToLinear ", logToLinear);
// set the output box
var outbox = document.getElementById("wSliderOutput");
outbox.innerHTML = Number(value).toFixed(2);
// set the linear scale on the slider
document.querySelectorAll(".optionSliders").forEach((optSlider) => {
if (optSlider.getAttribute("data-slider-type") == sliderType) {
optSlider.value = logToLinear;
}
var outBox = document.getElementById(outputName);
outBox.value = value;
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<html>
<head>
<title>Pow function for variable skew of data mapping</title>
</head>
<body>
Enter a float between -1.0 and 1.0, hit return, and cycle the slider.</br>
<input id="test" type="text" value="0.5" />
<input id="widthSlider" sliderName="widthSlider" type="range" min="1" value="20" max="200" data-slider-type="linesWidth">
<label for="widthSlider">L Width <span id="Width">
<output id="wSliderOutput"></output>
</span></label>
</body>
</html>
var widthSliderCurve = 0,42; // zwischen -1 und 1 – bestimmt die Art und Weise, wie der Bereich verzerrt wird
widthSlider.oninput = function () { var thisSlider = document.getElementById(“widthSlider”);
var curve = Math.pow(10, widthSliderCurve); // convert linear scale into lograthimic exponent for other pow function
var originalMin = 1.0; // these are set in the slider defintion in HTML make sure they match!
var originalMax = 200.0; // these are set in the slider defintion in HTML
var mappedOutputMin = 0.05; // this is the desired output min
var mappedOutputMax = 10; // this is the desired output max
var originalRange = originalMax - originalMin;
var newRange = mappedOutputMax - mappedOutputMin;
var zeroRefCurVal = thisSlider.value - originalMin; // zero referenced
var normalizedCurVal = zeroRefCurVal / originalRange; // normalized to 0-1 output
var rangedValue = ((Math.pow(normalizedCurVal, curve) * newRange) + mappedOutputMin).toFixed(2);
var outbox = document.getElementById("wSliderOutput");
outbox.innerHTML = rangedValue;
paper.tool.LineWidth = rangedValue;
//setLogSlider(rangedValue, widthSliderCurve, "L_Width", "wSliderOutput2");
}; setLogSlider = function (value, widthSliderCurve, sliderType, outputName) { /*** sicherstellen, dass die Konstanten mit den oninput-Funktionswerten übereinstimmen ***/ var curve = Math.pow (10, widthSliderCurve); var originalMin = 1,0; // Diese sind in der Slider-Definition in HTML festgelegt, stellen Sie sicher, dass sie übereinstimmen! var originalMax = 200,0; // diese werden in der Slider-Definition in HTML gesetzt var mappedOutputMin = 0.05; // das ist die gewünschte Ausgabe min var mappedOutputMax = 10; // das ist die gewünschte Ausgabe max var originalRange = originalMax – originalMin; var newRange = mappedOutputMax – mappedOutputMin; var logToLinear = Math.pow ((value – mappedOutputMin) / newRange, 1 / curve) * originalRange + originalMin; console.log(“logToLinear”, logToLinear); // setze das Ausgabefeld var outbox = document.getElementById(“wSliderOutput”); outbox.innerHTML = Zahl(Wert).toFixed(2); // setze die lineare Skala auf dem Slider document.querySelectorAll(“.optionSliders”).forEach((optSlider) => { if (optSlider.getAttribute(“data-slider-type”) == sliderType) { optSlider.value = logToLinear; } var outBox = document.getElementById(outputName); outBox.value = value; }); };
var widthSliderCurve = 0,42; // zwischen -1 und 1 – bestimmt die Art und Weise, wie der Bereich verzerrt wird
widthSlider.oninput = function () { var thisSlider = document.getElementById(“widthSlider”);
var curve = Math.pow(10, widthSliderCurve); // convert linear scale into lograthimic exponent for other pow function
var originalMin = 1.0; // these are set in the slider defintion in HTML make sure they match!
var originalMax = 200.0; // these are set in the slider defintion in HTML
var mappedOutputMin = 0.05; // this is the desired output min
var mappedOutputMax = 10; // this is the desired output max
var originalRange = originalMax - originalMin;
var newRange = mappedOutputMax - mappedOutputMin;
var zeroRefCurVal = thisSlider.value - originalMin; // zero referenced
var normalizedCurVal = zeroRefCurVal / originalRange; // normalized to 0-1 output
var rangedValue = ((Math.pow(normalizedCurVal, curve) * newRange) + mappedOutputMin).toFixed(2);
var outbox = document.getElementById("wSliderOutput");
outbox.innerHTML = rangedValue;
paper.tool.LineWidth = rangedValue;