[JavaScript] Wie am besten schnelle Mausbewegung erkennen?

Dieses Thema im Forum "Webentwicklung" wurde erstellt von Murdoc, 31. Juli 2011 .

  1. 31. Juli 2011
    Wie am besten schnelle Mausbewegung erkennen?

    szenario:

    ich hab ein html-objekt, welches man mit der maus bewegen kann (drag). nun möchte ich gerne, dass man dieses objekt mit der maus auch durch die gegend werfen kann.

    d.h. kleine/normale bewegungen sollen das objekt entsprechend verschieben, schnelle und weite bewegungen sollen das objekt werfen (in einer transition, also animiert).

    jemand eine idee?

    ich steh mal so richtig auf dem schlauch.

    das problem ist nämlich, dass "mousemove" so schnell verarbeitet wird, dass man praktisch keine möglichkeit hat eine art historie anzulegen um die bewegungen zu vergleichen, weil es pro aufruf immer nur ein paar pixel sind die sich unterscheiden.

    vielleicht findet sich ja der ein oder andere as3-programmierer, der ein wenig aus dem flash-nähkästchen plaudern kann.

    pseudo-code mäßig:
    Code:
    wenn maus-bewegung == normal
     bewege objekt zu maus-position
    
    wenn maus-bewegung == schnell
     warte bis maus sich nicht mehr bewegt ...
     bewege objekt animiert zu maus-position
    
     
  2. 31. Juli 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    http://omnipotent.net/jquery.sparkline/

    Hier wird der Mouse speed in einem Graph angezeigt, heißt, man erfasst ihn irgendwie - hilft dir das?

    (Code ab Zeile 315 im Quelltext)
     
  3. 31. Juli 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    hier mal erste gehversuche:

    http://murdoc.eu/move
     
  4. 1. August 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    Aaalsooo bei mir wirft er das Objekt gerne mal in falsche Richtungen oder einfach gar nicht so, wie ich es beabsichtigt habe.. Also erste Gehversuche passt wohl. Habe beruflich zur Zeit viel mit JavaScript zu tun, wenn ich morgen früh nicht so früh raus müsste um daran weiterzubasteln würd ich jetzt noch was probieren, aber leider geht's grad nicht. Also vllt. morgen wenn ich mich dran erinner.... Die Geschwindigkeit bekommt man aber im Prinzip einfach über delta-Vektorrechnung raus würde ich sagen? Wäre wohl ein wenig unperformant das ganze beim onMouseMove Event auszuführen, aber in einem bestimmten Interval (klein genug damit's präzise bleibt) wär's sicher tragbar für die "heutigen" Rechner. onMouseMove wär vllt auch tragbar. Keine Ahnung inwieweit das Performance fressen würde. Muss man mal testen.
     
  5. 1. August 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    Im Chrome (Mac) habe ich einen grünen leeren Kasten. Sonst bewegt sich nichts.
     
  6. 1. August 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    anklicken und maus bewegen
     
  7. 2. August 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    Total unsauber, mit paar Fehlermeldungen, aber vom Prinzip her meine ich so (body durch beliebiges Element ersetzbar):
    Code:
    <html>
     <head>
     <title>Rapid Mouse Movement - RMM</title>
     <script>
     var RMM = {
     config: {
     speed: 50 // check interval, 50ms
     },
     mouseSpeed: 0,
     
     mouseX: 0,
     mouseY: 0,
     lastMouseX: 0,
     lastMouseY: 0,
     
     cronInterval: 0,
     
     init: function(speed) {
     RMM.config.speed = speed;
     cronInterval = setInterval("RMM.cronjob();", speed);
     document.body.onmousemove = RMM.listen;
     },
     
     listen: function(e) {
     e = e || window.event;
     if(e.pageX){
     x = e.pageX; 
     y = e.pageY;
     } else if(window.event && window.event.clientX) {
     var isStrictMode = document.compatMode 
     && document.compatMode != 'BackCompat' ? true : false;
     var scrollX = isStrictMode ? 
     document.documentElement.scrollLeft : document.body.scrollLeft;
     var scrollY = isStrictMode ? 
     document.documentElement.scrollTop : document.body.scrollTop;
     x = window.event.clientX + scrollX;
     y = window.event.clientY + scrollY;
     }
     RMM.mouseX = x;
     RMM.mouseY = y;
     console.log("MOUSE MOVE! X:"+x+", Y:"+y);
     },
     
     cronjob: function() {
     dX = Math.abs(RMM.mouseX - RMM.lastMouseX);
     dY = Math.abs(RMM.mouseY - RMM.lastMouseY);
     
     RMM.mouseSpeed = Math.sqrt(dX*dX+dY*dY);
     
     RMM.lastMouseX = RMM.mouseX;
     RMM.lastMouseY = RMM.mouseY;
     
     RMM.getSpeed("speed"); 
     },
     getSpeed: function(id) {
     document.getElementById(id).innerHTML = RMM.mouseSpeed;
     }
     };
     
     </script>
     </head>
     <body style="height:1000px; width:1000px; border:1px solid grey;" onload="RMM.init(50);" onmousemove="RMM.listen();">
     <p>Mouse Speed: <b id="speed">0</b></p>
     </body>
    </html>
    
    Außerdem solltest du dich mal mit Mathematik beschäftigen und dir statt "left right up down" richtige Richtungsvektoren errechnen
     
  8. 3. August 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    hab das mal implementiert:
    http://murdoc.eu/move/

    so ganz funktioniert es noch nicht.
    wenn man die maus schnell bewegt und dann nicht mehr, passiert nix mehr ^^
     
  9. 3. August 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    Ich denke für dieses vorhaben muss man erst einmal den Ablauf für diese Aktionen ermitteln:

    Person will Objekt bewegen:
    • Objekt greifen
    • Bewegen
    • Bewegung verlangsamen/Stoppen
    • Objekt loslassen


    Person will Objekt werfen:
    • Objekt greifen
    • Beschleunigen
    • Objekt in der Bewegung loslassen


    Nach dieser Erkenntnis ist mein Vorschlag die Geschwindigkeit des Objektes zu Protokollieren und nach dem Loslassen zu Ermitteln ob die Person die Geschwindigkeit kurz vor dem loslassen eindeutig gesenkt hat.

    Ist dies der Fall so sollte das Objekt nur verschoben/bewegt werden, ist dies nicht der Fall so liegt eine Wurf nahe.
     
  10. 3. August 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    Ich finde den Ansatz lediglich die aktuelle Geschwindigkeit zu nehmen schon ganz okay, dein Ansatz würde viel komplizierter sein und eher dazu dienen, dass man den Beschleunigungsvorgang des Objektes nach dem "loslassen" fortführen kann, um das ganze "realistischer" zu machen, aber darum geht es denke ich noch nicht. Man muss lediglich aus den dX und dY noch eine Art Richtungsvektor errechnen, und das Objekt dann, abhängig von der Geschwindigkeit, in die Richtung "werfen". - Bspweise Startgeschwindigkeit ist die letzte gemessene Cursorgeschwindigkeit, danach langsam sinkend.
    Die Richtung bekommst du, mr Murdoc, wenn du folgendes machst:
    X-LastX und Y-LastY. Ist relativ simpel. Negative Zahlen - nach unten bzw. nach links, positive Zahlen - nach oben bzw. nach rechts. Wie in einem Koordinatensystem, lediglich dass der (0|0) Punkt oben links ist. Aber das ist ja bekannt.
    Aus diesen Werten kannst du erstmal einen vorläufigen Wurf realisieren. Wenn du das ganze präziser willst, mit Mausgestern etc, solltest du ggf. Krümmungen der Mausbewegung mitbeachten und mit protokollieren, falls der User das Objekt "kreisförmig" werfen möchte.
    Bin gerade am Arbeitsplatz, kann also nicht testen. Werde ich wenn ich mich dran erinnere nachholen, wenn ich Zuhause bin..
     
  11. 18. September 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    http://mrdoob.com/projects/chromeexperiments/google_gravity/

    Hier scheint ja sowas benutzt worden zu sein. Vielleicht kann man da weiter zu googlen?
     
  12. 19. September 2011
    AW: Wie am besten schnelle Mausbewegung erkennen?

    Wo genau ist jetzt das Problem?

    Man pollt in zeitlich konstanten Perioden die Mausposition und rechnet den zurueckgelegten Weg aus. Man koennte z.B. die letzten 5 Punkte speichern und darueber mitteln, theoretisch geht es aber auch mit lediglich 2 Punkten. Als Weg nimmt man einfach den euklidischen Abstand zwischen 2 Punkten

    s = sqrt((x1-x2)² + (y1-y2)²).

    Die Geschwindigkeit rechnet man einfach aus indem man den Weg durch die Zeit teilt, wobei t unsere Zeitkonstante ist.

    v = s/t

    Wir haben jetzt also die Geschwindigkeit des Objekts mit der es gezogen wird.

    Die ganze Berechnung machen wir, wenn die Maus losgelassen wird (objekt onmouseup oder so). Wenn wir die Zeitkonstante sehr klein gewaehlt haben, koennten wir auch ueber mehrere Punkte mitteln.

    Zusätzlich brauchen wir noch den Richtungsvektor. Den bekommen wir auch wieder ganz einfach indem wir die letzte Position (x2, y2) und eine der vorhergehenden (x1, y1) betrachten.

    Unser Richtungsvektor hat nun die Koordinaten (x2-x1, y2-y1). Von dem koennte man jetzt den Winkel beta zur x-Achse ausrechnen.

    Das beta und v setzen wir jetzt einfach in die Gleichung des schrägen Wurfs ein (Wurfparabel – Wikipedia) und erhalten für die Folgezeitschritte neue x und y Werte des Objekts.

    Da die y Achse im Browser wahrscheinlich anders herum ist, muss der Term mit g, der die Gravitation mit einbezieht addiert und nicht subtrahiert werden.

    Moechte man keine Gravitation, d.h. das Objekt soll konstant in die Richtung fliegen, in der es losgelassen wurde, muss man den hinteren Term mit g bei der y Formel weglassen.

    Das ganze aber nur zum Verstaendnis, da es so im Physikunterricht behandelt worden ist.

    Einfacher programmatisch umzusetzen:

    Theoretisch kann man auch komplett ohne v und alpha arbeiten indem man einfach ein Vielfaches des ausgerechneten Richtungsvektors addiert, der ja bei höherer Geschwindigkeit eine groessere Laenge hat.

    Wir ermitteln also den Richtungsvektor der beiden letzten Punkte:
    v = (x2-x1, y2-y1)

    pro Zeitkonstante t nach dem Loslassen des Objekts addieren wir ein Vielfaches dieses Richtungsvektors auf den initialen Loslasspunkt p0 = (x2, y2):

    p0 + t*a*v

    t ist ein int, der die Zeitschritte seit Loslassen darstellt und a stellt einen Tuningfaktor dar, mit dem wir die Abwurfgeschwindigkeit anpassen koennen. Auf den y Wert des resultierenden Vektors koennen wir noch die Gravitation rechnen indem wir einfach g/2 * t² drauf rechnen. g ist hierbei eine Zahl, die die gewuenschte Graviation darstellen soll (sinnvoll ist wahscheinlich irgendwas zwischen 1 und 10).

    Das sind die Grundlagen um das ganze halbwegs physikalisch korrekt zu implementieren.
     
  13. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.