Trasteando con el DOM 4: colisionador de píxeles

Los dos métodos principales de javaScript para trabajar con el tiempo: setTimeout() y setInterval()

Tarsila do Amaral

archivado en: JavaScript / 6 octubre, 2014 / taller:

Sigo con esta serie de javaScript para diseñadores. En esta entrada veremos cómo funcionan los dos métodos principales de javaScript para jugar con el tiempo: setTimeout() y setInterval() y llevaremos a la práctica algunos conceptos de anatomía elemental que vimos en la entrada anterior. La práctica consistirá en construir un Colisionador de Píxeles, con el cual descubriremos quizás la existencia del escurridizo Píxel de Higgs. Vamos primero con la teoría.

setTimeout() sirve para lanzar una función una vez que hayan pasado n milisegundos. Su sintaxis básica es:

window.setTimeout(función, tiempo);

donde función es la función que llamamos pasado el tiempo indicado en el segundo parámetro. Por ejemplo, así llamaríamos a la funcionDelay pasados 2000 milisegundos:

window.setTimeout(funcionDelay, 2000);

Si el código a ejecutar es breve, podemos poner directamente una función anónima dentro del setTimeout:

window.setTimeout(function() {

// Aquí el tinglado

}, 2000);

Si necesitamos que se pueda detener el proceso, definimos el setTimeout como valor de una variable que nos servirá de id.

var idSetTimeout = window.setTimeout(funcionDelay, 2000);

De esa manera podemos pararlo con el método clearTimeout();

window.clearTimeout(funcionDelay, 2000);

setInterval() funciona de manera parecida, pero esta vez la función se llama de forma ininterrumpida cada vez que concluye el tiempo indicado. Así, por ejemplo, llamaríamos a la función funcionRecursiva cada 200 milisegundos:

var idSetInterval = window.setInterval(funcionRecursiva, 200);

Y al igual que en el caso anterior, contamos con otro método para detenerlo a partir del id:

window.clearInterval(idSetInterval);

Bueno, pues ya con esto podemos crear nuestro colisionador, que consistirá en un div en cual hay otros divs más pequeños, cada uno a un lado. Una vez pulsado un botón, los dos divs se irán desplazando horizontalmente hasta que cchoquen, momento en el que los eliminaremos y pondremos otro div (el pixel de Higgs). Quizás antes de ver la solución, o al menos una de las posibles, alguien se anime a intentarlo. No debería llevar más de una hora.

ver demo en plunker

 

El Gran Colisionador de Píxeles

Definimos unos pocos estilos. Aunque los píxeles deberían ser de 1 píxel de ancho por otro de alto, los podemos poner un poco más gorditos para que se vean bien.

#colisionador {

border-top: 1px solid #000;

border-bottom: 1px solid #000;

width: 100%;

height: 50px;

margin-top: 5px;

}

#empezar {

margin: 3em;

}

.oculto {

display:none;

}

.pixeles {

width: 5px;

height: 5px;

position: absolute;

top: 25px;

}

En el html solo ponemos un par de cosas y llamamos a una función cuando se cargue todo (onload).

<body onload="init()">

<div id="colisionador"></div>

<p>

<button id="empezar">Empezar Experimento</button>

</p>

</body>

En la función que inicializa la aplicación ponemos las escuchas necesarias para que el usuario empiece a interactuar. En nuestro colisionador solo hay una.

/* Esta es la función que se invoca cuando se carga el documento (el onload que hay en el tag body) */

function init() {

/* Le añadimos una escucha al botón. */

var botonEmpezar = document.getElementById('empezar');

botonEmpezar.addEventListener('click', cuentaAtras);

}

Lanzamos un mensaje de cuenta atrás que nos permite trabajar con setTimeout(). Esta manera de hacerlo, mediante funciones dentro de funciones, es poco elegante y escalable. En estos casos, en los que necesitamos que se ejecuten de forma ordenada operaciones asíncronas, conviene utilizar algún sistema de promesas.

function cuentaAtras() {

/* Ejemplo de inserción de html con createElement */

var mensajes = document.createElement('div');

mensajes.setAttribute('id', 'mensajes');

mensajes.textContent = "Empieza la cuenta atrás...";

document.getElementById('colisionador').appendChild(mensajes)

/* Vamos cambiando el mensaje en una serie de setTimeouts.  */

setTimeout(function() {

mensajes.textContent = "3...";

setTimeout(function(){

mensajes.textContent = "2...";

setTimeout(function(){

mensajes.textContent = "1...";

/* Lanzamos los píxeles */

lanzarPixeles();

}, 100);

}, 100);

}, 100);

}

Ponemos en marcha los píxeles.

function lanzarPixeles() {

/* Las variables se declaran siempre al principio de la función, aunque se definan más adelante */

var cadenaPixelIzquierdo, cadenaPixelDerecho, pixelIzquierdo, pixelDerecho, contador, boton;

var animacion;

/* Eliminamos el div de los mensajes */

document.getElementById('colisionador').removeChild(document.getElementById('mensajes'));

/* Escondemos el botón y le quitamos la escucha*/

boton = document.getElementById('empezar');

boton.classList.add('oculto');

boton.removeEventListener('click', cuentaAtras);

/* ponemos un pixel a la izquierda utilizando esta vez insertAdjacentHTML */

cadenaPixelIzquierdo = "<div class='pixeles' style='left:0; background:#900' id='pixelIzquierdo'></div>";

document.getElementById('colisionador').insertAdjacentHTML('afterbegin', cadenaPixelIzquierdo);

/* otro a la derecha */

cadenaPixelDerecho = "<div class='pixeles' style='right:0; background:#090' id='pixelDerecho'></div>";

document.getElementById('colisionador').insertAdjacentHTML('afterbegin', cadenaPixelDerecho);

pixelIzquierdo = document.getElementById('pixelIzquierdo');

pixelDerecho = document.getElementById('pixelDerecho');

/* Iniciamos el contador */

contador = 0;

/* Y los lanzamos uno contra otro */

animacion = window.setInterval(function() {

/* En cada vuelta comprobamos que no hayan colisionado con offset */

if ( pixelIzquierdo.offsetLeft < pixelDerecho.offsetLeft ) {

pixelIzquierdo.style.left = contador+'px';

pixelDerecho.style.right = contador+'px';

contador++;

} else {

/* Salimos del setInterval y llamamos a la función final */

clearInterval(animacion);

creaPixeldeHiggs();

}

}, 25);

}

Y cuando colisionan, crean el píxel de Higgs.

function creaPixeldeHiggs() {

var cadenaPixeldeHiggs, temporal;

/* Como vamos a hacer dos acciones sobre el elemento, lo guardamos en una variable */

var colisionador = document.getElementById('colisionador');

document.getElementById('colisionador').removeChild(document.getElementById('pixelIzquierdo'));

document.getElementById('colisionador').removeChild(document.getElementById('pixelDerecho'));

cadenaPixeldeHiggs = "<div class='pixeles' style='background:#009' id='pixeldeHiggs'></div>";

/* Ejemplo de inserción de html con innerHTML */

colisionador.innerHTML = cadenaPixeldeHiggs;

/* Una vez insertado, lo centramos jugando de nuevo con el .style */

temporal = colisionador.clientWidth / 2 ;

document.getElementById('pixeldeHiggs').style.marginLeft = temporal+'px';

}

|| Tags: ,

valoración de los lectores sobre Trasteando con el DOM 4: colisionador de píxeles

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 5 sobre 5 (2 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.