dedlfix: <input type="mathematik">

problematische Seite

Tach!

Gegeben sei ein Input-Element vom Typ range, also ein Slider. Der soll sich so verhalten, dass in der Mitte der Wert 1 liegt, Maximalwert soll 100 sein und Minimalwert 0.01. Aber so einfach ist es ja nicht. So ein Range-Input arbeitet linear, und ich brauch da wohl was logarithmisches oder vielleicht auch was anderes. Das ganze soll einen Multiplikator darstellen. Auf der rechten Seite oberhalb von 1 soll es im unteren Bereich recht fein verstellbar sein, und je weiter man zum Maximalwert kommt, desto weniger interessiert es, ob man da genaue Werte trifft. Analog dazu sollte es auf der linken Seite unterhalb von 1 zugehen. Wobei ich mir da noch nicht ganz sicher bin, da müsste ich mal sehen, wie es sich dann letztlich anfühlt, also welche Bewegung welche Änderung ergibt.

Aber wie gesagt, sowas kann der Range-Input nicht und man wird da was rechnen müssen, um von einem linearen Messwertgeber auf das gewünschte Verhalten zu kommen. Nur was? Meine Mathekenntnisse sind jedenfalls eingerostet.

Ich hab da auch mal ein kleines Fiddle vorbereitet. Falls es kaputtgeht, das ist der wesentliche Teil:

<input type="range" id="in" min="0" max="10000" step="1">
<output id="out"></output>
var inElement = document.querySelector('#in');
var outElement = document.querySelector('#out');
outElement.value = inElement.value;

inElement.addEventListener('input', function(event) {
 	outElement.value = f(inElement.value);
});

function f(x) {
  return x;
}

Die Funktion f() wäre also der gefragte Teil, wobei es mir hier auf die Idee ankommt, wie es zu lösen geht, und nicht auf den konkreten Code dazu. Die Werte von min, max und step sind keine Vorgaben und können am Ende so sein, wie es am besten für die Lösung passt.

dedlfix.

akzeptierte Antworten

  1. problematische Seite

    Du willst wahrscheinlich sowas:

    ValueErrechnet = 10^(V/2)-1

    Der Input liefert 0 bis 9.

    V : ValueErrechnet
    --------------------
    0	: 0
    1	: 2,16227766016838
    2	: 9
    3	: 30,6227766016838
    4	: 99
    5	: 315,227766016838
    6	: 999
    7	: 3161,27766016838
    9	: 31621,7766016838
    

    Spiele in der Formel mit der 10 und der 2 für Deine konkrete Anwendung...

    Andere Lösung, mit Sprüngen an den Grenzen der 10er-Potenzen:

    • Multipliziere Werte unter 11 mit 1
    • Multipliziere Werte unter 101 mit 10
    • Multipliziere Werte unter 1001 mit 100
    for( i = 1; i < 7; i++ ) {
        if ( V < 10 ^ i + 1 )  {
           return V * 10 ^ ( i - 1 );
        }
    }
    

    Du kannst statt der 10er Potenzen auch 2 oder sonstwas nehmen.

    1. problematische Seite

      Tach!

      Du willst wahrscheinlich sowas:

      ValueErrechnet = 10^(V/2)-1

      Vermutlich, aber in der konkreten Form ist das für mich nicht das gewünschte. Hier muss ich erstmal die Formel umstellen, um die für die gewünschten Grenzen die passenden Parameter zu errechnen, damit der Slider richtig kalibriert ist. Und dann sitzt die 1 leider auch noch nicht in der Mitte.

      Die Idee geht in die richtige Richtung, die 10^X-Variante ist da aber einfacher zu handhaben und skaliert in beide Richtungen gleich gut. Um den am Slider einzustellenden Grenzwert zu bekommen, geht die vergleichbar einfache Formel: Logarithmus zur Basis 10 vom Grenzwert des eigentlich gewünschten Bereichs.

      Aber vielleicht hat deine Lösung noch andere Vorteile, die ich aber aufgrund meines eingestaubten Wissens (und ebensolchem Tafelwerk) nicht erkenne.

      dedlfix.

      1. problematische Seite

        @@dedlfix

        Um den am Slider einzustellenden Grenzwert zu bekommen, geht die vergleichbar einfache Formel: Logarithmus zur Basis 10 vom Grenzwert des eigentlich gewünschten Bereichs.

        Wenn du nicht die im Dezimalsystem runden Grenzen 0.01 und 100 haben willst, kannst du den natürlichen Logarithmus nehmen und statt Math.pow(10, x) dann Math.exp(x) – und der Rechner hat weniger zu tun. #mikrooptimierung

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. problematische Seite

          Man kann beides haben:

          Da stets gilt $$a^x=e^{x \cdot ln a}$$ (was man durch beidseitiges Anwenden der $$ln$$-Funktion bestätigt), hat man insbesondere

          $$10^x=e^{x \cdot ln 10}=exp(2.3026 \cdot x)$$

          Der Rechner tut sich leichter, und man bekommt trotzdem die Grenzen 0.01 und 100 heraus.

          1. problematische Seite

            Hallo,

            zumindest für Intel x86/x64 gilt: Ob Exp oder 10^x - das muss mit $$x^y=2^{ylog2(x)}$$ approximiert werden. Es gibt eine Instruktion für $$ylog2(x)$$ und eine Instruktion für $$2^{x-1}$$, mit Einschränkungen auf dem Wertebereich, so dass man mit den Exponenten der Fließkommawerte herumfiddeln muss bevor man im erlaubten Bereich ist. Und das ist dem Vernehmen nach auch noch ungenau, man muss das noch nachbehandeln. Ich kann nicht sagen, dass ich José da wirklich verstanden hätte.

            D.h. man muss exp und 10^x beide auf 2^x abbilden, weshalb es wurscht ist, ob man Math.pow oder Math.exp verwendet.

            Wie es auf anderen Prozessoren aussieht, weiß ich nicht.

            Rolf

            --
            sumpsi - posui - clusi
  2. problematische Seite

    @@dedlfix

    Gegeben sei ein Input-Element vom Typ range, also ein Slider. Der soll sich so verhalten, dass in der Mitte der Wert 1 liegt

    1 = 10⁰

    Maximalwert soll 100 sein

    100 = 10²

    und Minimalwert 0.01.

    0.01 = 10⁻²

    Aber so einfach ist es ja nicht. So ein Range-Input arbeitet linear

    wie z.B. von −2 bis 2, wobei 0 in der Mitte ist.

    Wenn du den Wert des Sliders als Exponent zur Basis 10 nimmst, deckst du den gewünschten Bereich von 0.01 bis 100 ab, mit 1 in der Mitte.

    Codepen

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    1. problematische Seite

      Tach!

      Aber so einfach ist es ja nicht. So ein Range-Input arbeitet linear

      wie z.B. von −2 bis 2, wobei 0 in der Mitte ist.

      Wenn du den Wert des Sliders als Exponent zur Basis 10 nimmst, deckst du den gewünschten Bereich von 0.01 bis 100 ab, mit 1 in der Mitte.

      Ja, sehr schön. So hab ich mir das vorgestellt.

      Als ich mir die Kurve dazu hab malen lassen, hab ich mir gedacht: Das steigt zwar schön auf der rechten Seite an, aber was ist mit der linken? Aber das muss ja so sein. In einem linearen System ist zwischen 0 und 1 eben weniger Platz als zwischen 1 und 100. Ich war fälschlicherweise auf der Suche nach einer Kurve, die beidseitig vergleichbar aussieht. So eine bekommt man (vermute ich mal) zwar hin, aber es ist dann eine Gerade in einem System mit einer logarithmischen(?) Achse. Als Gerade sieht sie dann unspektakulär aus, aber ist eigentlich genau das was ich haben wollte.


      Codepen

      Kritik am Antwortgeber ist zwar im Allgemeinen nicht gern gesehen, ich übe sie mal trotzdem, weil ich weiß, dass du das nicht falsch verstehst. Deine Vorliebe für den Codepen in Ehren, aber dass ich als Spielwiese JSFiddle ausgesucht habe, hatte schon seinen Grund. Der ist, dass der Codpen übermäßig viel Platz (~50%) für die Ausgabe verwendet, in dem Fall aber die Ausgabe nur sehr klein ist. Das geht zu Lasten der Code-Teile, die im restlichen Teil sehr gequetscht aussehen. Die etwas höhere Schriftgröße trägt ebenfalls ihr Schärflein dazu bei. Resultat ist, dass so gut wie jede Codezeile umgebrochen werden muss, wenn man nicht gerade ein Sauna-Handtuch quergelegt als Bildschirmgröße hat. Das macht das Lesen recht mühsam. Ja, man kann die Code-Bereiche größenverändern, aber das geht immer zu Lasten der anderen beiden. Die Aufteilung beim JSFiddle empfinde ich in dem Fall deutlich komfortabler und als das für die Situation besser geeignete Werkzeug. Im Mittelpunkt stand ja auch das Javascript und weniger die HTML-Ausgabe.

      dedlfix.

      1. problematische Seite

        Hallo dedlfix,

        jsFiddle ist ja ab Werk auf "gerechter Anteil für alle" eingestellt und du kannst das hin- und herschieben.

        Das geht in Codepen auch, und die relative Anordnung kannst Du über ChangeView verändern. Man bekommt damit ein ziemlich großes JS-Fenster hin.

        Bei der Gelegenheit wollte ich übrigens "Full Screen" in CodePen ausprobieren, und, tja, was soll ich da jetzt sagen. Auf CodePen steht: "Feel free to pinch them in the leg for us."
        Sorry Gunnar, das tut jetzt ein bisschen weh… KNEIF 😉

        Rolf

        --
        sumpsi - posui - clusi
        1. problematische Seite

          Tach!

          Das geht in Codepen auch, und die relative Anordnung kannst Du über ChangeView verändern. Man bekommt damit ein ziemlich großes JS-Fenster hin.

          Im Change View finde ich nur die normale Editor View als das kleinere Übel. Alle anderen Ansichten gehen entweder nicht oder zeigen keinen Code. ... Ach, da unten in dem Menü gibts noch Editor Layout. Ja, das passt schon besser, wenn die Code-Teile links untereinander stehen und die Ausgabe rechts. Da kann man sich das angenehmer zurechtschieben. Kann man das als Ersteller so voreinstellen, dass man eine zum Problem besser passende Darstellung definieren kann, oder geht das nur individuell, wenn man weiß, wo man hingreifen muss?

          Jedenfalls löst sich damit ein Großteil der Kritik auf und Codepen lässt sich doch auf ein für diesen Fall passendes Werkzeug einstellen.

          dedlfix.