DesarrolloLibre

Desarrollo Web, Android, juegos y mucho más

10-11-2015

En esta entrada veremos cómo crear un sistema de partículas empleando JavaScript y Canvas como el siguiente:

Creando el sistema de partículas (JavaScript)

Al igual que siempre, primero les presento el código completo del experimento de partículas el cual analizaremos en la siguiente sección:

    var c = document.getElementById("canvas-club");
    var ctx = c.getContext("2d");
    var w = c.width = window.innerWidth;
    var h = c.height = window.innerHeight;
    var particles = [];
    var maxParticles = 100;
    var size = 5;
    var r = size / 2;
    var clearColor = "rgba(0, 0, 0, .1)";

    function random(min, max) {
        return (Math.random() * (max - min)) + min;
    }

    function P() {
    }

    P.prototype = {
        init: function () {
            this.x = random(0, (w - size));
            this.y = h + random(0, 20);
            this.vx = 0;
            this.vy = random(-1, -2);
        },
        draw: function () {
            var hue = (h - this.y) * .6;

            ctx.fillStyle = "hsla(" + hue + ", 100%, 50%, .8)";
            ctx.strokeStyle = "hsla(" + hue + ", 100%, 50%, " + this.alpha + ")";
            ctx.lineWidth = r / 2;

            ctx.beginPath();
            ctx.arc(this.x + r, this.y + r, r, 0, 2 * Math.PI, false);
            ctx.fill();

            this.update();
        },
        update: function () {

            this.x += this.vx;
            this.y += this.vy;
            this.vx *= 1.15;
            if (this.y < h * .8 && Math.random() > .5) {
                this.vx = random(-1, 1);
                this.vy -= .05;
            }

            if (this.y + 50 < 0) {
                this.init();
            }
        }
    }

    function setup() {

        for (var i = 0; i < maxParticles; i++) {
            (function (x) {
                setTimeout(function () {
                    var p = new P();
                    p.init();
                    particles.push(p);
                }, x * 100)

            })(i);
        }
    }
    function anim() {

        for (var i in particles) {
            var p = particles[i];
            p.draw();
        }

        ctx.fillStyle = clearColor;
        ctx.fillRect(0, 0, w, h);

        window.requestAnimationFrame(anim);
    }

    setup();
    anim();

Analizando el código JavaScript anterior...

Primero quisiera comenzar con algunas consideraciones:

  • Cada partícula es pintada independientemente de las demás en en Canvas como podrás ver el el método draw.
  • A las partículas se les varía el color según la distancia recorrida.
  • La cola de las partículas se logra re-pintando un fondo oscuro transparente sobre todo el Canvas cada vez que se pinten las partículas.

Ahora si veamos en detalle el sencillo código JavaScript.

Variables Globales

En la primera sección son declaradas todas las variables globales; entre las mismas se encuentran aquellas que permiten acceder al Canvas y su contexto, además de las dimensiones del Canvas:

    var c = document.getElementById("canvas-club");
    var ctx = c.getContext("2d");
    var w = c.width = window.innerWidth;
    var h = c.height = window.innerHeight;

Las partículas tendrán tamaños, colores y velocidades distintas que son calculadas aleatoriamente (Ramdom), estas características mencionadas son registradas a través de un conjunto de variables; las partículas serán almacenadas en un array en donde una partícula corresponde a una posición del array:

    var p = new P();
    p.init();
    particles.push(p);

La "clase base" de las partículas

Empleamos la propiedad prototype para crear una especie de "clase base" para nuestras partículas y acceder a sus propiedades:

function P() {}

    P.prototype = {
        init: function () {
            this.x = random(0, (w - size));
            this.y = h + random(0, 20);
            this.vx = 0;
            this.vy = random(-1, -2);
        },
        draw: function () {
            var hue = (h - this.y) * .6;

            ctx.fillStyle = "hsla(" + hue + ", 100%, 50%, .8)";
            ctx.strokeStyle = "hsla(" + hue + ", 100%, 50%, " + this.alpha + ")";
            ctx.lineWidth = r / 2;

            ctx.beginPath();
            ctx.arc(this.x + r, this.y + r, r, 0, 2 * Math.PI, false);
            ctx.fill();

            this.update();
        },
        update: function () {

            this.x += this.vx;
            this.y += this.vy;
            this.vx *= 1.15;
            if (this.y < h * .8 && Math.random() > .5) {
                this.vx = random(-1, 1);
                this.vy -= .05;
            }

            if (this.y + 50 < 0) {
                this.init();
            }
        }
    }

Más información sobre la propiedad prototype en: MDN: Object.prototype.

Como su nombre indica, la función draw pinta los pequeños círculos que son nuestras partículas.

La función update altera el comportamiento de las partículas, cambiando por valores aleatorios (o inicializando la posición una vez que no sean visibles dentro del Canvas) la posición y velocidad de las mismas.

Creando la estructura para todas las partículas

Con la función setTimeout se agregan partículas poco a poco en base a un intervalo de tiempo variante:

    function setup() {

        for (var i = 0; i < maxParticles; i++) {
            (function (x) {
                setTimeout(function () {
                    var p = new P();
                    p.init();
                    particles.push(p);
                }, x * 100)

            })(i);
        }
    }
Se van creando, pintando y animando las partículas poco a poco; esto da como resultado que las partículas se van mostrando progresivamente y no todas agrupadas de una vez.

Pintando las partículas (animando)

En esta sección pintamos una partícula por vez y empleamos el método window.requestAnimationFrame que ya fue tratado en una entrega anterior llamada: EL SECRETO DE LAS ANIMACIONES EN JAVASCRIPT (REQUESTANIMATIONFRAME()); recordando un poco el uso de la función Window.requestAnimationFrame(), permite animar figuras dibujadas en un elemento Canvas:

    function anim() {
        ctx.fillStyle = clearColor;
        ctx.fillRect(0, 0, w, h);

        for (var i in particles) {
            var p = particles[i];
            p.draw();
        }
        window.requestAnimationFrame(anim);
    }

Las líneas de código:

    ctx.fillStyle = clearColor;
    ctx.fillRect(0, 0, w, h);

Pintan un rectángulo negro transparente con el objetivo de mostrar una cola a los círculos moviéndose; mientras más claro el color de fondo, más largo será esta cola dejada por las partículas:

Cola Partícula

Si no fuera pintado este fondo negro transparente nuestro experimento quedaría de la siguiente forma:

Partícula sin fondo negro transparente

El resto del código JavaScript es de facil interpretación; de nuevo les dejo el enlace del experimento original: CodePen: Livelines.


Publicidad

Give me for a beer!

Algunos recursos que te pueden interesar

Wave World con Canvas

Wave World con Canvas

Corazón con CSS

Corazón con CSS

anime.js librería para animaciones en JavaScript

anime.js librería para animaciones en JavaScript

Algunos artículos que te pueden interesar

Los mejores plugin WYSIWYG para JavaScript

Los mejores plugin WYSIWYG para JavaScript

Se presentan algunos plugins gratuitos WYSIWYG para JavaScript que no son más que una interfaz que permite dar formato al texto introducido mediante HTML; en esencia permite enriquecer el texto introducido mediante un procesador de texto.

Andrés Cruz 28-03-2016

La API de Reconocimiento de Voz en JavaScript: speechRecognition()

La API de Reconocimiento de Voz en JavaScript: speechRecognition()

La API de Reconocimiento de Voz da la capacidad a nuestras aplicaciones de reconocer la voz según el idioma configurado a través del micrófono de la PC o dispositivo móvil.

Andrés Cruz 27-04-2015

Animando cosas con CSS

Animando cosas con CSS

Muchos cosas se pueden hacer con un poco de CSS y algo de imaginación, en esta entrada veremos algunos experimentos curiosos con animaciones que pueden servir (por ejemplo) como icono para la "Carga de Página" en nuestro site.

Andrés Cruz 22-06-2015