2012-08-29 5 views
5

Ho provato ad implementare una pagina panoramica trascinando. Nella mia implementazione la pagina si sposta per un po 'dopo che l'utente ha rilasciato il pulsante del mouse, come trascinare le mappe in Google Maps. Ora mi piacerebbe evitare questo effetto, quando il mouse non si muove più quando l'utente rilascia il pulsante. Il problema è che non riesco a capire come rilevare se il mouse si muove davvero quando viene attivato l'evento mouseup.Come rilevare se il mouse si muove quando viene lanciato mouseup?

Per ora ho provato ad affrontare questo problema calcolando la velocità di trascinamento e quindi confrontare la velocità con una "sensibilità" pre-valutata, che funziona la maggior parte del tempo, ma a volte fallisce.

Esempio semplificato a jsFiddle. Quando si suona con il violino, si prega di utilizzare il tasto centrale in FF, il div draggabble "si attacca" al pulsante sinistro.

Pseudocodice:

AniMove = function (doc, element, sensitivity, panspeed, duration) { 
    var mouseDown = function (e) { 
      sTime = new Date(); 
      originalX = mouseX = e.clientX; 
      originalY = mouseY = e.clientY; 
      /* addEventListeners mousemove & mouseup for document */ 
      return; 
     }, 
     mouseMove = function (e) { 
      /* Setting new position for #square + new mouseX & Y */ 
      return; 
     }, 
     mouseUp = function() { 
      var dc = 1; 
       /* removeEventListeners mousemove & mouseup */ 
       eTime = new Date(); 
       vX = Math.round((50 * panspeed) * (originalX - mouseX)/(eTime - sTime)); 
       vY = Math.round((50 * panspeed) * (originalY - mouseY)/(eTime - sTime)); 

      // Check whether mouse is moving or not, 
      // now checking the speed against sensitivity, which is not reliable 

       if (Math.abs(vX) < sensitivity){vX = 0;} 
       if (Math.abs(vY) < sensitivity){vY = 0;} 

       for (n = 0; n < dur; n++, dc += 0.001) { 
        vX = Math.round(vX * dec/dc); 
        vY = Math.round(vY * dec/dc); 
        delay[n] = setTimeout(endDrag(n, vX, vY), n * 50); 
       } 
       return; 
      }, 
      endDrag = function (n, vX, vY) { 
       /* Setting new position for #square */ 
       return; 
      }, 
      dec = 1 - 120/duration; 
    panspeed *= -0.01; 
    duration /= 50; 
    element.addEventListener('mousedown', mouseDown, false);  
} 
drag = new AniMove(document, document.getElementById('square'), 20, 100, 500); 

Quindi, è anche possibile rilevare se il mouse è in movimento o non in questa situazione? Forse ho bisogno di un approccio diverso per questo compito?

risposta

2

Un'idea è mantenere attivo il listener mouseMove per 0,5 secondi dopo il mouseUp (imposta un timer), se il mouse si è spostato in tale 0,5 secondi (cioè la posizione del mouse è diversa da quella di mouseUp) quindi assumere c'era movimento e lo animava.

Potrebbe essere necessario giocare con il .5 secondo per vedere cosa dà il miglior feeling.

+0

Grazie, ora funziona! Il pensiero 10 ms ha fatto il trucco. Working fiddle: http://jsfiddle.net/cww55/7/ – Teemu

0

Vuoi che la vista continui a spostarsi e si fermi gradualmente, giusto?

Tutto quello che dovete fare è notare quanto si stava muovendo velocemente PRIMA dell'evento MouseUp, quindi ridurre la velocità in incrementi di oltre mezzo secondo circa. Dovrebbe essere irrilevante se il mouse continua a muoversi se il pulsante non è premuto.

Una volta che hai "lasciato andare la palla", la velocità con cui rotola non ha nulla a che fare con ciò che fa la tua mano dopo.

Quindi, è necessario tenere traccia della velocità del mouse mentre il pulsante è abbassato, quindi basta "fade out" una volta che il pulsante è alzato.

Nel tuo caso, se il mouse non si muoveva quando il pulsante è stato rilasciato, l'analogia è che l'utente ha "tenuto sulla palla". Quindi dovrebbe fermarsi immediatamente.

Quindi non è necessario fare nulla di speciale per gestire quella situazione. Se l'utente arresta il mouse con il pulsante premuto, interrompe il panning.

+0

Corretto, ma solo se l'utente rilascia il pulsante del mouse quando il mouse è ancora in movimento. Se il mouse si è fermato prima che il pulsante venga rilasciato, mi piacerebbe evitare l'arresto graduale e avere invece un normale panorama. – Teemu

+0

Quindi, elaborare gli eventi MouseMove. Ricorda il tempo e la posizione del corrente e del precedente. Questo ti dà la velocità del puntatore quando il pulsante del mouse è stato rilasciato. Non è necessario sapere o preoccuparsi di ciò che accadrà dopo. – Ben