2012-08-29 27 views
5

He intentado implementar una vista panorámica de la página arrastrando. En mi implementación, la página se mueve durante un tiempo después de que el usuario suelta el botón del mouse, como arrastrar mapas en Google Maps. Ahora me gustaría evitar este efecto, cuando el mouse ya no se mueve cuando el usuario suelta el botón. El problema es que no puedo descubrir cómo detectar si el mouse se mueve realmente cuando se dispara el evento mouseup.¿Cómo detectar si el mouse se está moviendo cuando se dispara el mouseup?

Por ahora he tratado de resolver este problema calculando la velocidad de arrastre y luego comparo la velocidad a una "sensibilidad" prevaluada, que funciona la mayor parte del tiempo, pero a veces falla.

Ejemplo simplificado en jsFiddle. Cuando juegue con el violín, use middlebutton en FF, el draggabble div "se pega" al botón izquierdo.

Pseudocódigo:

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

lo tanto, es posible la determinación de si el ratón se está moviendo o no en esta situación? Tal vez necesito un enfoque diferente para esta tarea?

Respuesta

2

Una idea es mantener el mouseMove escucha activa durante .5 segundo después del mouseUp (establecer un temporizador), si el mouse se ha movido en .5 segundos (es decir, la posición del mouse es diferente de lo que era en mouseUp) entonces asumir hubo movimiento y lo animó.

Es posible que deba jugar con .5 segundos para ver qué le da la mejor sensación.

+0

¡Gracias, ahora funciona! Pensamiento 10 ms hizo el truco. Violín de trabajo: http://jsfiddle.net/cww55/7/ – Teemu

0

Quiere que la vista siga moviéndose y se detenga gradualmente, ¿no?

Todo lo que necesita hacer es observar qué tan rápido se estaba moviendo ANTES del evento MouseUp, luego reduzca la velocidad en incrementos de más de medio segundo más o menos. No debería ser relevante si el mouse continúa moviéndose si el botón no está abajo.

Una vez que haya "soltado la pelota", lo rápido que rueda no tiene nada que ver con lo que su mano hace a continuación.

Por lo tanto, debe rastrear la velocidad del mouse mientras el botón está presionado, y luego simplemente "atenuarse" una vez que el botón esté activado.

En su caso, si el mouse no se movía cuando se soltó el botón, la analogía es que el usuario se ha "aferrado a la bola". Por lo tanto, debe detenerse de inmediato.

Así que no necesita hacer nada especial para manejar esa situación. Si el usuario detiene el mouse con el botón hacia abajo, deje de panoramizar.

+0

Correcto, pero solo si el usuario suelta el botón del mouse cuando el mouse aún se está moviendo. Si el mouse se ha detenido antes de que se suelte el botón, me gustaría evitar detenerlo gradualmente, y tener un panorama normal en su lugar. – Teemu

+0

Así que solo procesa los eventos de MouseMove. Recuerde la hora y la posición de la corriente y la anterior. Eso le da la velocidad del puntero cuando se suelta el botón del mouse. No necesita saber o preocuparse por lo que sucede a continuación. – Ben

Cuestiones relacionadas