¿Cómo crear un efecto de onda con Canvas y JavaScript?

- Andrés Cruz

In english

¿Cómo crear un efecto de onda con Canvas y JavaScript?

Ver ejemplo

En esta entrada veremos cómo crear una onda como la siguiente:

 

Para esto usaremos el elemento Canvas provista por HTML5 y la función llamada Window.requestAnimationFrame() introducida 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; en otras palabras:

Con la función requestAnimationFrame() se obtienen transiciones o cambios suaves a través de una API que se encuentra optimizado para trabajar con el Canvas.

Para más información, vea el enlace anterior.

Construyendo la onda (JavaScript)

El JavaScript es en realidad corto y sencillo; pero a su vez puede resultar algo enredado debido a las operaciones matemáticas de sumas y divisiones pero trataré de explicarlo de la manera más sencilla.

Antes de mostrar el código es necesario recordar la función seno o coseno que seguramente viste en el colegio y universidad; estas funciones son como olas que vienen y van:

función Coseno

Imagen obtenida de: Coseno.

La función coseno o seno nos viene de maravilla para realizar este experimento y esto es debido a su efecto de ola u onda que poseen; si no recuerdas que son estas funciones en Internet conseguirás bastante material al respecto.

Volviendo a la aplicación de estas funciones en JavaScript tenemos que:

  • Math.cos(n) es empleada para aplicar el coseno.
  • Math.sin(n) es empleada para aplicar el seno.

Finalmente les presento el código JavaScript completo:

    var c = document.getElementById('canv');
    var $ = c.getContext('2d');

    var w = c.width = window.innerWidth;
    var h = c.height = window.innerHeight;

    var draw = function(t) {
      $.lineWidth = 1;
      $.fillStyle = 'rgb(0, 0, 0)';
      $.fillRect(0, 0, w, h);

      for (var i = -60; i < 60; i += 1) {
        $.strokeStyle = 'rgb(255, 255, 255)';
        $.beginPath();
        $.moveTo(0, h / 2);
        for (var j = 0; j < w; j += 10) {
          $.lineTo(10 * Math.cos(i) +
            j + (0.008 * j * j),
            Math.floor(h / 2 + j / 2 *
              Math.cos(j / 50 - t / 50 - i / 118) +
              (i * 0.9) * Math.cos(j / 25 - (i + t) / 65)));
        };
        $.stroke();
      }
    }
    var t = 0;

    window.addEventListener('resize', function() {
      c.width = w = window.innerWidth;
      c.height = h = window.innerHeight;
    }, false);

    var run = function() {
      window.requestAnimationFrame(run);
      t += 5;
      draw(t);
    };

    run();

Como podrás imaginar, el HTML consisten en una simple etiqueta Canvas.

Algunas consideraciones sobre el JavaScript anterior

Primero Inicializamos algunas variables globales para obtener acceso al elemento Canvas, su contexto y dimensiones:

var c = document.getElementById('canv');    var $ = c.getContext('2d');    var w = c.width = window.innerWidth;    var h = c.height = window.innerHeight;

Dentro de la función draw()

Definimos algunos estilos a las líneas que vamos a pintar:

$.lineWidth = 1;
$.fillStyle = 'rgb(0, 0, 0)';
$.fillRect(0, 0, w, h);
$.strokeStyle = 'rgb(255, 255, 255)';

Este primer for permite dibujar un conjunto de líneas en paralelo; al variar la cota inferior y superior podemos crear ondas más o menos anchas; además este for se encarga de inicializar componentes necesarios para pintar líneas.

    for (var i = -60; i < 60; i += 1) {
              $.beginPath();
              $.moveTo(0, h / 2);
                       /*For anidado*/
              $.stroke();
            }

En otras palabras, si este for no estuviera, nuestra onda se vería como un látigo:

Onda látigo

El siguiente código es un for anidado que pinta w líneas por vez; en donde w es el ancho de la pantalla:

    for (var j = 0; j < w; j += 10) {
      $.lineTo(10 * Math.cos(i) +
        j + (0.008 * j * j),
        Math.floor(h / 2 + j / 2 *
          Math.cos(j / 50 - t / 50 - i / 118) +
          (i * 0.9) * Math.cos(j / 25 - (i + t) / 65)));
    };

Como podrás ver, empleamos múltiples funciones cosenos (Math.cos) para crear un variado efecto onda (y no tan constante como el coseno).

Las divisiones y multiplicaciones por números bajos es para mantener los valores lo más "constantes" posibles y que la onda no vaya a variar de tamaño radicalmente a medida que los valores de los fors (var j y var i) aumenten.

Para tener una animación variada, cada vez que se ejecuta recursivamente la función draw() a través de la función window.requestAnimationFrame(run); se varía el valor de la variable t para tal fin.

Finalmente creamos la función run() la cual es invocada al cargar la página web.

var run = function() {
      window.requestAnimationFrame(run);
      t += 5;
     draw(t);
};

Este experimento fué tomado de CodePen: Wind y modificado a gusto.

Ver ejemplo

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz En Udemy

Acepto recibir anuncios de interes sobre este Blog.

!Cursos desde!

10$

En Udemy

Quedan 4d 18:53!


Udemy

!Cursos desde!

4$

En Academia

Ver los cursos

!Libros desde!

1$

Ver los libros
¡Hazte afiliado en Gumroad!