Damián De Luca - Capacitación & Desarrollo Web

Animación con HTML5 Canvas y Javascript

En este ejemplo vamos a aprender como animar un círculo para obtener la impresión de que está rebotando dentro de un cuadro. El resultado final de este ejemplo puede verse aquí.

Documento básico en HTML5

Partiremos de un documento básico en HTML5

<!DOCTYPE html>
<head>
<title>HTML5 Ejemplo 1</title>
</head><body>
<canvas id="miCanvas" height="200" width="400"
style="border: 1px solid #c3c3c3">
</canvas>
</body>
</html>

Como ven, dentro del cuerpo del documento (body) definimos un elemento canvas. Este elemento permite realizar dibujos y cargar imágenes en su interior y es el que nos hará posible realizar la animación. Los atributos que especificamos para este ejemplo son el alto (height) y el ancho (width). También le agregamos un borde mediante el atributo style. Si no ponemos esto último, no veremos los límites de nuestro canvas.

A continuación dibujaremos la pelota y luego la animaremos, empleando técnicas relacionadas con Javascript y Canvas de HTML5.

Dibujando una pelota

Pensemos siempre al elemento canvas como un lienzo de pintura o como una hoja en blanco. Para poder comenzar a dibujar necesitamos de la ayuda de Javascript. Vamos a incluir dentro de nuestro documento una porción de código de este lenguaje. Recordemos que se ubica siempre entre las etiquetas <head> y </head>.

<script type="text/javascript">
var contexto;
window.onload = function() {
    can = document.getElementById("miCanvas");
    contexto = can.getContext("2d");
    dibujar();
}
function dibujar() {
    contexto.strokeStyle = "#000000";
    contexto.fillStyle = "blue";
    contexto.beginPath();
    contexto.arc(40,100,50,0,Math.PI*2,true);
    contexto.closePath();
    contexto.stroke();
    contexto.fill();
}
</script>

Veamos la primer función. window.onload = function() se refiere a un evento de navegador, nos dice que defina la función que está entre llaves para cuando ocurra ese evento. ¿Y cuándo ocurre? Cuando el navegador termina de cargar la página por completo.

Como ven en la primer línea de la función, obtenemos el elemento canvas mediante document.getElementById que es una función de Javascript que selecciona el elemento cuyo atributo id indicamos entre comillas. En este caso, el elemento miCanvas.
Luego, se obtiene el contexto para dibujar en 2d, esto es una característica propia de HTML5.

Y por último hacemos una llamada a la función dibujar() que está definida más abajo. Noten que se definió afuera de las funciones la variable contexto para que sea accesible desde ambas como una variable global.

Antes de continuar, aclaremos qué hubiera ocurrido si no utilizábamos el evento window.onload. En ese caso, el código Javascript se hubiera ejecutado sin que la página hubiera estado cargada y por lo tanto el elemento miCanvas aún no se hubiera creado. El resultado hubiera sido un error.

Ahora sí, analicemos la función dibujar(). Usamos siempre la variable contexto para poder acceder al canvas. Con strokeStyle definimos el color del pincel con el que vamos a dibujar, #000000 es el código hexadecimal del color negro. El pincel comprende todos los trazos que hagamos y los bordes de las figuras que dibujemos.

A continuación con fillStyle elegimos el color con el que llenaremos las figuras geométricas.

Con beginPath damos por comenzado un trazo, sería el equivalente a apoyar el lápiz sobre la hoja de papel.

Con arc vamos a dibujar un arco. Los dos primeros parámetros de esta función dicen en qué punto del canvas se ubicará tomando como referencia la esquina superior izquierda del rectángulo en el que se circunscribe el círculo. Debemos aclarar que cada punto es un píxel y que el cero de las coordenadas del canvas se encuentra en el extremo superior izquierdo. Debido a esto, las x se incrementan hacia la derecha como en un gráfico habitual, pero las y se incrementan a medida que bajamos en el canvas, al revés de lo que podría esperarse. El siguiente parámetro es el radio del arco en píxeles. Los dos parámetros que siguen son el ángulo de inicio y ángulo de fin. Si especificamos un arco entre 0 y 2 pi, estaremos definiendo un círculo. El último parámetro, que es booleano, es decir solo puede tomar valor true o false, sirve para marcar el sentido horario en que dibujemos el arco. En este caso, como dibujaremos todo el arco, no importa qué valor definamos.

Con closePath cerramos el trazo, y con stroke indicamos que queremos que se dibuje. Estas dos últimas instrucciones serían el equivalente a levantar el lápiz del papel luego de haber hecho un trazo.

Por último, fill se encarga de rellenar lo que hayamos encerrado por el trazo con el color que especificamos antes con fillStyle.
Con esas instrucciones ya tendremos dibujada nuestra pelota en el canvas.

Hasta aquí, el ejemplo debería verse como así

Animando la pelota

Ahora llega el momento de hacer que nuestra pelota haga algo. Vamos a hacer que se mueva hacia un lado de forma horizontal y que cuando llegue a los límites del canvas cambie de dirección. De esta manera dará la sensación de estar rebotando de un extremo al otro.
Para ello utilizaremos el siguiente código Javascript en lugar del que teníamos hasta ahora.

<script type="text/javascript">
var posX;
var can;
var contexto;
var direccion;
window.onload = function() {
    can = document.getElementById("miCanvas");
    contexto = can.getContext("2d");
    posX=15;
    direccion = 0;
    setInterval("dibujar()",2);
}
function dibujar() {
    if (direccion == 0)
        posX++;
    else
        posX--;
if (posX==350)
        direccion = 1;
    if (posX==50)
        direccion = 0;

    can.width = can.width; // limpia el canvas
    contexto.strokeStyle = "#000000";
    contexto.fillStyle = "blue";
    contexto.beginPath();
    contexto.arc(posX,100,50,0,Math.PI*2,true);
    contexto.closePath();
    contexto.stroke();
    contexto.fill();
}
</script>

Analicemos nuevamente por función. Primero, en el evento onload del navegador observamos algunos cambios. En principio, aparece la variable posX, que está definida como global para dibujar() también. Esta variable indicará la coordenada de x para ubicar la pelota en nuestro canvas. En esta instrucción, le asignamos un 15 para inicializarla. Recordemos que esta función onload se ejecuta al cargarse el navegador y después no se vuelve a ejecutar.

Luego aparece la variable direccion, que pasa a valer 0, es también una inicialización, veremos bien lo que hace esta variable en la función dibujar().

A continuación tenemos una función muy importante de Javascript: setInterval. Su mecanismo es simple: recibe dos parámetros, una función y un número en milisegundos. Lo que hará a partir de que se la invoca es contar desde 0 hasta el número que le pasamos y cuando llegue, llamará a la función que indicamos como primer parámetro. Luego, comenzará a contar nuevamente. Es decir, realizará reiteradas llamadas a nuestra función a intervalos regulares. Nos ayudará a para actualizar la posición de la pelota en el canvas.

Observemos ahora la función dibujar(). Expliquemos qué hace la variable direccion que ya había aparecido antes. Se encarga de definir el sentido en que se moverá la pelota. Ya habíamos mencionado que posX definía la posición de la pelota. Por eso, mediante estructuras condicionales cambiamos la dirección de la pelota si esta llega a los bordes del canvas. Únicamente cambia la dirección en esos casos, sino no se está en uno de ellos, incrementamos o decrementamos posX para posibilitar el desplazamiento de la pelota. Observen que para el borde izquierdo usamos el valor 0, lo cual resulta lógico, pero para el segundo usamos 350, sabiendo que el canvas tiene 400 píxeles de ancho. ¿Por qué? Porque debemos descontar el diámetro del círculo, para que el cambio de dirección ocurra cuando el borde del círculo «toca» contra el borde del canvas. Si hubiéramos puesto 400, veríamos que la pelota sigue camino y se corta hasta desaparecer y recién ahí cambia de dirección y vuelve desplazada hacia el otro lado.

Antes de dibujar la pelota usamos can.width = can.width. Es un truco que sirve para limpiar el canvas y borrar todo lo que se tenía dibujado. Luego dibujamos nuevamente la pelota, pero desplazada porque usamos la variable posX, que ya está actualizada, en lugar de definir un valor constante como teníamos antes.

Por acción de todo este código Javascript, el resultado final será nuestra pelota azul rebotando de un extremo a otro del canvas como vimos al principio de la entrada.

Salir de la versión móvil