El efecto luciérnaga
Spanish (Español) translation by Luis Chiabrera (you can also view the original English article)
Las imágenes cósmicas se utilizan en muchos sitios web como imagen de fondo. Esas imágenes son indudablemente hermosas, pero después de todo son imágenes que proporcionan poca vivacidad. Con jQuery, podemos aportar una imagen cósmica de treinta años añadiendo algo de polvo (partículas) espaciales que vuelan como luciérnagas. En este tutorial, veremos cómo implementar este efecto en 30 minutos. También aprenderemos un poco de técnicas Javascript orientadas a objetos.
Caracteristicas
- Las partículas se mueven a velocidades y direcciones aleatorias (movimiento browniano).
- Se proporcionan cuatro modelos de partículas en este tutorial. Cada uno tiene un aspecto ligeramente diferente.
- El número total de partículas es configurable.



Estaremos contemplando este fondo cósmico durante bastante tiempo. Para que nuestros ojos se sientan más cómodos, se utiliza una imagen oscura y simple como fondo en este tutorial. Siéntete libre de usar imágenes más coloridas en tus propios proyectos.
Las partículas
Para que este efecto se vea más realista, tenemos cuatro modelos de partículas en este tutorial. Son pequeñas imágenes con diferente tamaño y apariencia. Mira la figura a continuación para obtener más detalles:
- La partícula 1 es más pequeña pero más brillante. Parece que está bien enfocado para que podamos verlo claramente.
- La partícula 4 es más grande pero más oscura (tan oscura que apenas se puede ver), que imita un objeto fuera de foco.



El HTML
A diferencia de la mayoría de los tutoriales, es el fondo de una página web en la que nos centraremos hoy, lo que hace que el HTML sea bastante simple:
- No hay elementos dentro de la etiqueta del cuerpo. Entonces nada nos distraerá del fondo y la animación.
- Con la definición CSS, se establece un fondo cósmico para el cuerpo de esta página. Esto debería ser muy sencillo.
- jQuery se incluye como de costumbre.
1 |
|
2 |
<html>
|
3 |
<head>
|
4 |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
5 |
<title>The Firefly Effect</title> |
6 |
<style>
|
7 |
body { |
8 |
margin: 0; |
9 |
background: #000 url(images/bg.jpg) 60% 0 no-repeat; |
10 |
}
|
11 |
</style>
|
12 |
</head>
|
13 |
<body>
|
14 |
|
15 |
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> |
16 |
<script type="text/javascript"> |
17 |
// The magic goes here...
|
18 |
</script>
|
19 |
|
20 |
</body>
|
21 |
</html>
|
JavaScript orientado a objetos
Ahora echemos un vistazo más de cerca a la vida de una partícula. Cada partícula puede diferir en apariencia. Y se mueven a diferentes velocidades y direcciones. Pero todos siguen el mismo conjunto de reglas que pueden describirse como una secuencia de acciones:
- Elige aleatoriamente un modelo de partículas.
- Crea un DOM para esta partícula.
- Genera una velocidad aleatoria para esta partícula.
- Genera la posición inicial (Punto X y Punto Y) para esta partícula.
- Mostrar la partícula en la posición generada en 4.
- Genera otra posición (Punto X y Punto Y) a la que se mueve la partícula.
- Animar el movimiento de partículas a la posición generada en 6.
- Repite 6 y 7 una vez que finalice la animación mencionada en 7.



Cada partícula sigue exactamente estos ocho pasos a lo largo de su vida útil. Y los factores aleatorios, como la posición y la velocidad, hacen que cada partícula se comporte de una manera única. Este es un caso perfecto para implementar algunas técnicas de programación orientadas a objetos. Vamos a envolver estos ocho pasos en una 'clase' que se instanciará muchas veces para crear múltiples instancias de la misma lógica. Cada instancia (partícula) se ejecuta en un carril separado y tiene su propia velocidad y dirección.
Es importante tener en cuenta que no hay clases en JavaScript. Las funciones se pueden usar para simular clases, pero en general JavaScript está basado en prototipos más que en clases. Todo es un objeto. Para obtener más información sobre cómo definir e instanciar una 'clase' de JavaScript, consulta estos artículos.
En este mismo efecto, se define una 'clase' y luego se instancia 50 veces con el siguiente código.
1 |
|
2 |
function Particle() {
|
3 |
// 1. Randomly pick a particle model. |
4 |
// 2. Create a DOM for this particle. |
5 |
// 3. Generate a random speed for this particle. |
6 |
// 4. Generate the initial position (Point X and Point Y) for this particle. |
7 |
// 5. Display the particle at the position generated in 4. |
8 |
// 6. Generate another position (Point X and Point Y) to which the particle moves. |
9 |
// 7. Animate the particle movement to the position generated in 6. |
10 |
// 8. Repeat 6 and 7 once the animation mentioned in 7 finishes. |
11 |
}; |
12 |
|
13 |
function randomInt(max) {
|
14 |
// Generate a random integer (0 <= randomInt < max) |
15 |
return Math.floor(Math.random() * max); |
16 |
} |
17 |
|
18 |
$(function(){
|
19 |
var total = 50; |
20 |
var particles = []; |
21 |
|
22 |
for (i = 0; i < total; i++){
|
23 |
particles[i] = new Particle(); |
24 |
} |
25 |
}); |
- La lógica de ocho pasos está envuelta en una función llamada Partícula. Definir una función es la forma de definir una 'clase' en Javascript.
- Tendremos que generar muchos enteros aleatorios en este efecto, desde la velocidad hasta las posiciones X-Y. Entonces, escribe una función para este único propósito y nómbrala randomInt. Genera un entero aleatorio menor que un número dado. Usaremos esta función de vez en cuando, así que no lo olvides.
- Al final, instanciamos la función Partícula en un bucle, creando 50 instancias de partículas, cada una de las cuales se almacena en una matriz llamada partículas. Presta atención a la palabra clave 'nueva' que usamos para crear una instancia de un objeto.
Algunas configuraciones básicas
En esta sección, definiremos propiedades y métodos para la clase Particle. Y veremos cómo elegir aleatoriamente un modelo de partículas.
Podemos usar la palabra clave 'this' para definir propiedades para una 'clase'. Cuando se trata de definir métodos, la propiedad 'prototipo' es el camino a seguir. Mira el código a continuación y daremos algunas explicaciones.
1 |
|
2 |
function Particle() {
|
3 |
this.path = 'images/'; |
4 |
this.images = ['particle1.png', 'particle2.png', 'particle3.png', 'particle4.png']; |
5 |
|
6 |
// Randomly Pick a Particle Model |
7 |
this.image = this.images[randomInt(this.images.length)]; |
8 |
this.file = this.path + this.image; |
9 |
|
10 |
// Create a Particle DOM |
11 |
this.element = document.createElement('img');
|
12 |
|
13 |
// A Sequence of Actions to Take |
14 |
this.speed().newPoint().display().newPoint().fly(); |
15 |
}; |
16 |
|
17 |
// Generate a Random Speed |
18 |
Particle.prototype.speed = function() {};
|
19 |
|
20 |
// Generate a Random Position |
21 |
Particle.prototype.newPoint = function() {};
|
22 |
|
23 |
// Display the Particle |
24 |
Particle.prototype.display = function() {};
|
25 |
|
26 |
// Animate Particle Movements |
27 |
Particle.prototype.fly = function() {};
|
- En las líneas 2 y 3, definimos la ruta y los nombres de archivo de nuestras imágenes de partículas. Hay más de una imagen de partículas, por lo que las almacenamos en una matriz (una propiedad de Partícula).
- En la línea 6, se toma una imagen de partícula aleatoria de la matriz mencionada anteriormente. Aquí se usa la función randomInt que definimos anteriormente. Muy útil, ¿eh?
- En la línea 7, concatenamos la ruta y el nombre del archivo.
- En la línea 10, se crea un img DOM. Este es el contenedor de una partícula.
- La línea 13 es el núcleo de este efecto. Una secuencia de métodos se llama en una cadena. Esta única línea de código cubre los pasos 3 a 8 mencionados en la sección anterior. Revisaremos cada uno de estos métodos muy pronto.
- Desde la línea 17 hasta el final, se definen cuatro métodos para la clase Particle. Cada uno de ellos se encarga de una cosa en particular para una partícula. Speed() genera la velocidad aleatoria. NewPoint() genera un conjunto aleatorio de posición X-Y. Display() se asegura de que la partícula se muestre correctamente. Y fly() se encarga de la animación.
- Presta atención a la forma en que definimos los métodos para una 'clase' en las líneas 17, 20, 23 y 26. Los nuevos métodos se definen en la propiedad prototipo de una clase. Puede parecer un poco complicado para los chicos con experiencia en C, Java o PHP (como yo). Si te sientes incómodo con esto, no dudes en pasar un minuto leyendo este artículo.
De hecho, hay muchas formas diferentes de definir propiedades y métodos para una clase Javascript. Aquí hay un gran artículo sobre este tema.
Velocidad aleatoria
Por ahora, tenemos una idea de cómo funciona este efecto. A partir de esta sección, comenzaremos a escribir funciones que usamos para manipular el movimiento de una partícula.
Primero, generemos una velocidad aleatoria para una partícula. La velocidad determina qué tan rápido viaja una partícula. Si estás familiarizado con jQuery, comprenderás que no podemos simplemente pasar a velocidad real, digamos 100 píxeles por segundo. De hecho, el parámetro utilizado para describir la velocidad en jQuery es la duración medida en milisegundos. Entonces, la pregunta es cómo generar una duración razonable en la que una partícula viaja de un lugar a otro. ¿Qué pasa con el siguiente código?
1 |
|
2 |
// Generate Random Speed |
3 |
Particle.prototype.speed = function() {
|
4 |
this.duration = (randomInt(10) + 5) * 1000; |
5 |
|
6 |
return this; |
7 |
}; |
- En la línea 3, simplemente generamos un número entero aleatorio entre 5000 y 14000. Es decir, una partícula mantendrá su velocidad y dirección sin cambios durante 5 a 14 segundos antes de girar y moverse hacia otro lugar.
- Mira la línea 5. ¿Por qué devolvemos esto? ¿Recuerdas que estas funciones se llamarán en cadena? Devolver el objeto original garantiza que la función de seguimiento funcione correctamente. Necesitaremos esto también en otros métodos.
- Una vez que se ejecuta esta función, se puede acceder a una propiedad de duración en una instancia de Particle.
Posición aleatoria
Un conjunto aleatorio de posición X-Y es muy útil en este efecto. Se puede usar para determinar:
- En ese punto, una partícula aparece inicialmente,
- Hasta qué punto una partícula se mueve una vez que nace o termina un viaje.
Aquí está el código que necesitamos para generar un conjunto aleatorio de posición X-Y.
1 |
|
2 |
// Generate a Random Position |
3 |
Particle.prototype.newPoint = function() {
|
4 |
this.pointX = randomInt(window.innerWidth - 100); |
5 |
this.pointY = randomInt(window.innerHeight - 100); |
6 |
|
7 |
return this; |
8 |
}; |
El tamaño de la ventana actual del navegador se puede recuperar de window.innerWidth y window.innerHeight. Si una partícula vuela más allá del límite de la ventana, aparecerán barras de desplazamiento. Es posible que no queramos que eso suceda. Así que limitemos el movimiento de partículas en un área que es 100 píxeles menos alta y ancha que la ventana del navegador. El código anterior debería ser bastante sencillo. Después de ejecutar esta función, las propiedades pointX y pointY se vuelven accesibles. Una vez que la función se ejecuta por segunda vez, pointX y pointY se renovarán en la instancia de Particle.
Mostrar la partícula
En secciones anteriores, ya se creó un img DOM para una nueva partícula. Ahora vamos a establecer algunos atributos y mostrar la partícula en algún lugar de la ventana del navegador. Esto se logra con el siguiente código.
1 |
|
2 |
// Display the Particle |
3 |
Particle.prototype.display = function() {
|
4 |
$(this.element) |
5 |
.attr('src', this.file)
|
6 |
.css('position', 'absolute')
|
7 |
.css('top', this.pointY)
|
8 |
.css('left', this.pointX);
|
9 |
$(document.body).append(this.element); |
10 |
|
11 |
return this; |
12 |
}; |
- En la línea 3, this.element contiene el img DOM creado. Estableceremos atributos para ello en esta función.
- En la línea 4, this.file contiene la imagen aleatoria que seleccionamos de los cuatro modelos de partículas. Al establecer el atributo src, traemos la imagen de la partícula al nuevo img DOM.
- Con las líneas 5 a 7, la partícula se coloca en algún lugar de la ventana del navegador.
- En la línea 8, el img DOM que se acaba de crear se agrega al cuerpo. La partícula nunca aparecerá a menos que escribamos esta línea de código simple.
Animar movimientos de partículas
Finalmente, hemos llegado a la parte de animación que puede resultar más simple de lo que pensabas.
La función animada en jQuery hará el truco por nosotros. Se necesitan cuatro parámetros: animado(parámetros, duración, flexibilización, devolución de llamada). Consulta la documentación si no tienes idea de lo que haces.
1 |
|
2 |
// Animate Particle Movements |
3 |
Particle.prototype.fly = function() {
|
4 |
var self = this; |
5 |
$(this.element).animate({
|
6 |
"top": this.pointY, |
7 |
"left": this.pointX, |
8 |
}, this.duration, 'linear', function(){
|
9 |
self.speed().newPoint().fly(); |
10 |
}); |
11 |
}; |
Lo que hace el código anterior es bastante simple:
- Anima la partícula a una posición aleatoria.
- La animación tarda this.duration milisegundos en completarse.
- La partícula se mueve a velocidad constante. (El modo de aceleración es 'lineal').
- Una vez que se completa la animación, el código en la línea 8 se ejecutará como devoluciones de llamada.
- En la línea 8, se generará una nueva velocidad, se calculará una nueva posición y la función fly() (la misma que estamos escribiendo en esta sección) se ejecutará nuevamente.
- Repite desde el paso 1.
Entonces la función fly() se llama a sí misma repetidamente. Con esta función recursiva, la animación sigue y sigue para siempre. Por ahora, podemos escribir la historia completa de la vida de una partícula. ¿Todavía recuerdas la siguiente cadena?
1 |
|
2 |
this.speed().newPoint().display().newPoint().fly(); |
Repasemos lo que hace:
- Se genera una nueva velocidad.
- Se calcula un nuevo conjunto de posición X-Y.
- La partícula aparece en la posición calculada en el Paso 3.
- Se calcula una nueva posición.
- La partícula se mueve a la posición calculada en el Paso 5.
- Se genera nueva velocidad.
- Se calcula un nuevo conjunto de posición X-Y.
- La partícula se mueve a la posición calculada en el Paso 7.
- Una vez que se complete la animación, repita desde el paso 6.
Si estos pasos te parecen un trabalenguas ... Bueno, mira esta figura nuevamente. Deberías poder codificar cada paso ahora. Y debes saber cómo organizar todas las cosas en una estructura orientada a objetos. Finalmente el efecto de luciérnaga está completo.



Conclusión
Ahora todos deberían poder implementar este efecto en sus propios proyectos. Esperemos que también comprendas mejor el Javascript orientado a objetos.
Lo principal que me encanta de este efecto es que al cambiar el fondo y las imágenes de partículas, puedes producir un aspecto completamente diferente. Puedes tener aviones o incluso superhombres volando en tu página web si lo deseas. Tu imaginación es el límite.
Eso es todo por este tutorial. Espero que lo disfrutes. ¡Gracias por leer!



