Efectos Fantasmales con jQuery

Por user Nestor Plasencia Prado
Efectos Fantasmales con jQuery

En este tutorial utilizaremos fadeIn y fadeOut de jQuery para dar efectos a un fantasma creado con CSS.

¡Hola, amigos de Devcode! En esta oportunidad aprenderemos a utilizar las propiedades position en css y los efectos de fadeIn y fadeOut con jQuery, creando un pequeño juego para atrapar un fantasma.

Iniciamos agregando la librería de jQuery a Codepen.

En HTML añadiremos un título usando el elemento h3, creamos un

 con el id de "contenedor", que tiene como elemento hijo un
con el id de "fantasma".

¡Atrápame, si puedes!

 
 

En CSS, centramos el texto del elemento h3.

h3 {
  text-align: center;
}

Añadimos al contenedor las propiedades de ancho alto y un margen para poder centrar el elemento, adicionalmente le asignamos un color para su visualización.

#contenedor {
  width: 560px;
  height: 300px;
  margin: 0 auto;
  background-color: #333;
}

Al div fantasma también le agregamos las propiedades de ancho y alto, además de un color totalmente opuesto en contraste al usado en el contenedor.

#fantasma {
  width: 50px;
  height: 60px;
  background-color: white;
}

En esta ocasión haremos uso de la propiedad position, para la ubicación del elemento fantasma dentro del contenedor.

En el elemento fantasma, utilizaremos el valor de absolute para position. Esto le da posición relativa al primer antecesor con una posición no estática.

#fantasma {
  position: absolute;
  left: 250px;
  top: 100px;
}

Para que ese antecesor no estático, sea el elemento contenedor, utilizamos el valor de relative para la propiedad position.

#contenedor {
  position: relative;
}

Ahora con las propiedades left y top podemos controlar la ubicación de fantasma dentro del contenedor.


Con algunos estilos, como border-radius y border-bottom, generamos la silueta de un fantasma, el color del borde inferior tiene que coincidir con el color de contenedor, creando así la apariencia de un par de piernas.

#fantasma {
    /*Form*/
  background-color: white;
  border-radius: 30px 30px 0px 0px;
  border-bottom: 4px dashed #333;
}

Para humanizar nuestro personaje, le añadimos unos ojos y una boca. En HTML agregamos dos divs con la clase ojos, y entre ellos la letra "w".

    w

En CSS, usamos el valor de inline-block para la ubicación de los ojos, damos un ancho y alto, creamos los ojos circulares con border-radius, agregamos un borde, y con margin los ubicamos en la estructura del fantasma.

.ojo {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 4px solid #333;
  margin: 15px 3px 3px;
}

Adicionalmente para la boca utilizaremos el tipo de letra  "Lucida Console"

#fantasma {
  font-family: "Lucida Console", Monospace;
}

Con esto habremos terminado con la parte gráfica de la aplicación.


Haciendo uso de jQuery vamos a obtener la posición del mouse dentro de la ventana.

$("#contenedor").mousemove(function(event) {
    let posx = event.pageX;
    let posy = event.pageY;
});

Para obtener la posición del mouse relativa al elemento contenedor, debemos restar la posición del mismo elemento contenedor referente a la ventana, esto mediante offset.

let posx = event.pageX - $(this).offset().left;
let posy = event.pageY - $(this).offset().top;

Ahora obtendremos la posición del fantasma dentro del contenedor. Añadimos la mitad de las medidas de ancho y alto, así el punto de referencia será el centro del fantasma.

let fanx = parseInt($('#fantasma').css("left")) + 25;
let fany = parseInt($('#fantasma').css("top")) + 30;

Creamos la función distancia, que retornará la diferencia de posición entre dos puntos.

function distancia(x1, x2, y1, y2) {
    return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}

Añadimos un condicional que testea si es que la distancia entre la posición del mouse se encuentra a un radio de 120 píxeles, referente a la posición del fantasma. De ser así, cambiará la posición del fantasma aleatoriamente dentro del contenedor.

if (distancia(posx, fanx, posy, fany) < 120) {
    let valx = Math.floor((Math.random() * 510) + 1);
    let valy = Math.floor((Math.random() * 235) + 1);
    $('#fantasma').css("left",valx+"px");
    $('#fantasma').css("top",valy+"px");
}

Para agregar robusticidad a nuestra aplicación, colocaremos una condicional que evitará que la posición aleatoria se encuentre cerca a la posición del mouse.

if (distancia(posx, valx, posy, valy) >= 150) {
    $('#fantasma').css("left",valx+"px");
    $('#fantasma').css("top",valy+"px");
}

Ahora añadimos el método fadeOut para desaparecer el elemento de forma rápida antes de cambiarle la posición. Y el método fadeIn de forma lenta para aparecer en su nueva posición.

if (distancia(posx, valx, posy, valy) >= 150) {
    $("#fantasma").fadeOut("fast", function() {
        $('#fantasma').css("left",valx+"px");
        $('#fantasma').css("top",valy+"px");
    });
    $("#fantasma").fadeIn("slow", function(){});
}

Pero ahora ha surgido un problema que no habíamos percibido anteriormente: el cambio de posición se realiza muchas veces sucesivas, ya que el evento de dispara múltiples veces. Para evitar este comportamiento, crearemos una bandera que evitará esta multiplicidad. Así formará parte del condicional, desactivándose al iniciar el cambio de posición y volviendo a activarse al finalizar este.

var band = 1;
if (distancia(posx, fanx, posy, fany) < 120 && band == 1)
if (distancia(posx, valx, posy, valy) >= 150) {
    band = 0;
    $("#fantasma").fadeOut("fast", function() {
        $('#fantasma').css("left",valx+"px");
        $('#fantasma').css("top",valy+"px");
    });
    $("#fantasma").fadeIn("slow", function() {band = 1;});
}

Ahora el fantasma solo cambiara de posición una vez.


Si deseas aprender mas de programación, recuerda que en Devcode tenemos el Curso de jQuery y muchos otros cursos esperando por ti para ayudarte a complementar tu aprendizaje. No olvides compartir el tutorial con tus amigos y dejarnos tus dudas u opiniones en la caja de comentarios.

user

Nestor Plasencia Prado

Programmer | Developer | Maker | Robot Designer | Knowmad