jueves, 11 de septiembre de 2014

Javascript Scripting: Swipe para menú lateral en PhoneGap

Hoy traigo una tecnología que si bien no toqué mucho, me parece mas interesante para hacer aplicaciones que para hacer videojuegos, no obstante hay videojuegos muy sencillos que con este framework pues no te andas con rodeos ya que javascript es muy, muy sencillo de aprender y maquetar con html no es algo complejo de aprender tampoco y sinceramente, da bastantes buenos resultados.

En este caso pondré un ejemplo de swipe para un menú lateral muy sencillo y si bien podría mejorar la funcionalidad, para lo que lo usé en su momento, realmente funcionaba lo suficientemente bien.

Por supuesto es bastante aplicable a cualquier tipo de swipe, solo se tendría que adaptar un poco a la condición que se desee, en este caso tengo el caso de un swipe horizontal y otro vertical.

Pasemos al código:

//Mínimo de píxeles de distancia a recorrer para activar el swipe
var swipeMinDistanceX = 100;
var swipeMinDistanceY = 100;

//Variables globales necesarias para funcionamiento interno
var swipeStartX;
var swipeStartY;

//Eventos touch
function initSwipe()
{
    document.addEventListener("touchstart", swipeStartHandler, true);
    //document.addEventListener("touchmove", swipeMoveHandler, true);
    //document.addEventListener("touchenter", endHandler, true);
    //document.addEventListener("touchleave", endHandler, true);
    document.addEventListener("touchend", swipeEndHandler, true);
    //document.addEventListener("touchcancel", cancelHandler, true);   
}

//Cancelar eventos
function cancelSwipe()
{
    document.removeEventListener("touchstart", swipeStartHandler, true);
    //document.removeEventListener("touchmove", swipeMoveHandler, true);
    //document.removeEventListener("touchenter", endHandler, true);
    //document.removeEventListener("touchleave", endHandler, true);
    document.removeEventListener("touchend", swipeEndHandler, true);
    //document.removeEventListener("touchcancel", cancelHandler, true);   
    
}

//Al empezar a tocar
function swipeStartHandler(startEvent)
{
    var touchStart = startEvent.changedTouches[0];
    swipeStartX = touchStart.clientX;
    swipeStartY = touchStart.clientY;
}

//Al hacer drag
function swipeEndHandler(moveEvent) 
{
    var touchMove = moveEvent.changedTouches[0];
    var moveX = touchMove.clientX;
    var moveY = touchMove.clientY;
    
    if(Math.abs(moveX - swipeStartX) > Math.abs(moveY - swipeStartY)) //Drag Horizontal
    {
        if ((moveX - swipeStartX) > swipeMinDistanceX) //Drag Derecha
        {
            Capa.className= "Mostrar"; //Muestra la capa
        }

        if ((moveX - swipeStartX) < -swipeMinDistanceX) //Drag Izquierda
        {
            Capa.className= "Ocultar"; //Oculta la capa
        }
    } else { //Drag Vertical
        if ((moveY - swipeStartY) > swipeMinDistanceY) //Drag Abajo
        {
            
        }
        
        if ((moveY - swipeStartY) < -swipeMinDistanceY) //Drag Arriba
        {
            
        }
    }
};
Empecemos a desglosar este pequeño script:

//Mínimo de píxeles de distancia a recorrer para activar el swipe
var swipeMinDistanceX = 100;
var swipeMinDistanceY = 100;

//Variables globales necesarias para funcionamiento interno
var swipeStartX;
var swipeStartY;
Aquí decimos el mínimo de píxeles a recorrer para activar el swipe como puse en el comentario, y después dos variables internas que simplemente guardarán mas adelante el valor de la posición en la que empezaremos a hacer el swipe.

//Eventos touch
function initSwipe()
{
    document.addEventListener("touchstart", swipeStartHandler, true);
    //document.addEventListener("touchmove", swipeMoveHandler, true);
    //document.addEventListener("touchenter", endHandler, true);
    //document.addEventListener("touchleave", endHandler, true);
    document.addEventListener("touchend", swipeEndHandler, true);
    //document.addEventListener("touchcancel", cancelHandler, true);   
}

//Cancelar eventos
function cancelSwipe()
{
    document.removeEventListener("touchstart", swipeStartHandler, true);
    //document.removeEventListener("touchmove", swipeMoveHandler, true);
    //document.removeEventListener("touchenter", endHandler, true);
    //document.removeEventListener("touchleave", endHandler, true);
    document.removeEventListener("touchend", swipeEndHandler, true);
    //document.removeEventListener("touchcancel", cancelHandler, true);   
    
}
Estas dos funciones son las que llamaremos para iniciar el swipe y cancelarlo en caso de que ya no querramos usar el swipe en nuestro dispositivo, he dejado comentado algunos eventos que tiene PhoneGap para controlar la pulsación de nuestra pantalla, que si bien no usamos aquí, está bien saber cuales son por si en algún caso nos hiciese falta, cuando querramos que se habilite esta función que estamos creando llamaremos a initSwipe() y cuando querramos cancelarla pues llamaremos a cancelSwipe().

//Al empezar a tocar
function swipeStartHandler(startEvent)
{
    var touchStart = startEvent.changedTouches[0];
    swipeStartX = touchStart.clientX;
    swipeStartY = touchStart.clientY;
}
Esta función se llama swipeStartHandler, por ser el nombre que se ha asociado al evento touchstart, de manera que es cuando empezaremos a hacer el movimiento con nuestro dedo en la pantalla, aquí usaremos las dos variables que declaramos al principio para guardar la posición X e Y respectivamente de la pantalla donde empezamos a mover nuestro dedo, en este caso, el primer dedo que hayamos puesto en la pantalla, startEvent, que es el parámetro que recibimos, le pedimos el primer dedo que ha sufrido un cambio, ya sea de posición o cualquier cosa y de ahí podemos extraer la información delas coordenadas en las que se encuentra.

//Al hacer drag
function swipeEndHandler(moveEvent) 
{
    var touchMove = moveEvent.changedTouches[0];
    var moveX = touchMove.clientX;
    var moveY = touchMove.clientY;
    
    if(Math.abs(moveX - swipeStartX) > Math.abs(moveY - swipeStartY)) //Drag Horizontal
    {
        if ((moveX - swipeStartX) > swipeMinDistanceX) //Drag Derecha
        {
            Capa.className= " transition mostrar"; //Muestra la capa
        } else { //Drag Izquierda
            Capa.className= "transition ocultar"; //Oculta la capa
        }
    } else { //Drag Vertical
        if ((moveY - swipeStartY) > swipeMinDistanceY) //Drag Abajo
        {
            
        } else { //Drag Arriba
            
        }
    }
};
Y por último en este último método, se le llamará automáticamente al terminar de hacer swipe, es decir, al soltar el dedo de la pantalla, ya que la función swipeEndHandler la tenemos asociada al evento touchend como podemos ver mas arriba.

En este caso he usado Capa.className para especificar que oculte o muestre una capa, en caso de querer saber como hacer esto a través de CSS como ha sido este caso, es tan sencillo como esto:

.Capa.mostrar{
    -webkit-transform: translate3d(75%, 0, 0); 
    transform: translate3d(75%, 0, 0);
}
.Capa.ocultar{
    -webkit-transform: translate3d(0, 0, 0); 
    transform: translate3d(0, 0, 0);
}
.transition { 
    -webkit-transition-duration: .25s; 
    transition-duration: .25s; 
} 
Siendo el porcentaje, el porcentaje de la pantalla que ocupará esta capa y en transition pues la duración del movimiento, que en este caso es un cuarto de segundo (25 centésimas) para darle un efecto de desplazamiento.

En esta función comprobamos que, hayamos desplazado mas horizontal que verticalmente primero, para saber que tipo de movimiento es, y las condiciones de dentro pues tenemos nuestros respecticos movimientos (Drag) comentados para saber cual es cual, y como podremos ver es tan sencillo como ver si el movimiento viene de la izquierda o la derecha con tan solo ver donde empezamos el movimiento y donde lo acabamos.

Si bien esta función tiene sus limitaciones, no es difícil de perfeccionar y especialmente puede ser muy útil para cualquier persona que esté aprendiendo o quiera aprender a usar los eventos de pulsación de pantalla.

No soy un gran experto en PhoneGap, así que si hay algo que no está explicado correctamente o podría explicarse mejor, que es muy probable, quizás lo pueda corregir con el tiempo, aunque ciertamente al menos el comportamiento que ha tenido es justo el que yo he necesitado en su momento.

No hay comentarios:

Publicar un comentario