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í.

Animación con HTML5 Canvas y JavaScript

La estructura HTML

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 con HTML5 Canvas y JavaScript

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.

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();
}

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:

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();
}

Analizando el código de la animación con HTML5 Canvas y JavaScript

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.

La función dibujar()

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.

Comentarios finales sobre este proyecto

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 este artículo.

Más sobre Diseño y desarrollo Web


Desarrollador apasionado por las tecnologías web, con experiencia en lenguajes (x)HTML, CSS, PHP, Java, Javascript, AJAX y MySQL. También en sistemas de publicación CMS como WordPress y frameworks como Code Igniter. Además se especializa en sistemas GNU/Linux siendo también un difusor del Software Libre. En el ámbito laboral se desempeñó como programador web, webmaster y como administrador de sistemas llevando adelante procesos de migración a Software Libre. Estudia la carrera de Licenciatura en Análisis de Sistemas en la Facultad de Ingeniería de la UBA y se desempeña como programador freelance.

34 Comentarios en “Animación con HTML5 Canvas y JavaScript

  1. Damian dice:

    Hola! Mira la verdad que estoy muy entusiasmado en lo que es HTML 5, vengo de las versiones anteriores de HTML/CSS y esto es un gran salto, es mi parecer.
    Te cuento que copio el codigo tal cual lo tenes publicado y lo leo, pero no me hace el efecto que t hace a vos. A mi, de forma local, me muestra que arranca desde el lado izquierdo, pero solo veo la mitad de la pelota y desaparece hacia la izquierda.
    Espero poder solucionar esto y tambien una respuesta tuya.
    Vengo siguiendo todos tus post y la verdad que muy buenosss!!!
    Desde ya, muchas gracias.

    Saludos,
    Damian.-

  2. Guillermo dice:

    buenísimo che!!!! estoy tratando de armar páginas con animaciones sin recurrir a flash ahora que surgió HTML5 y esta explicación me viene muy bien para armar empezar a diseñar un menú dinámico, cuando lo pueda hacer te comento como fue

    muchísimas gracias!!!

    saludos
    Guille

  3. Nicolas dice:

    Hola. Muy buena la animación. Ahora, una pregunta: Si en vez de dibujar quiero poner una imagen, donde hago el cambio?
    Saludos y gracias!

  4. yosseph dice:

    buen ejemplo pero como debo hacer para que la pelota rebote (en zic zag) espero que me ayuden .

    • tury dice:

      Hola Yosseph

      Es muy buena tu pregunta.
      Supongo que el zig zag que mencionas es que la pelota pueda moverse hacia arriba y abajo con la capacidad de rebotar en los bordes superior e inferior. Para poder lograrlo conviene pensarlo de la siguiente manera. La pelota actualmente se está moviendo en una única dimensión y queremos que lo haga en una más. La estructura que necesitaremos es la misma que la que ya tenemos, pero agregando esta nueva dimensión. Si añadimos una variable posY que indique la posición vertical en donde se encuentra la pelota y una variable direccionV que toma el valor 0 si se mueve hacia abajo ó 1 si se mueve hacia arriba, tendremos casi todo resuelto.

      La estructura de programación, como dije, es exactamente igual a la de la dimensión que teníamos, solo debemos cambiar las variables y tener algunas consideraciones. A partir de ahora, cada vez que se dibuje la pelota, debemos pasarle como parámetro la variable posY al método arc. Tenemos que fijarnos bien los límites en donde la pelota choca considerando el radio (50 arriba y 150 abajo). No hay que olvidar que el canvas tiene el 0 del eje Y de coordenadas en la esquina superior izquierda y que se incrementa hacia abajo.

      Aquí está el ejemplo hecho para que puedas ver que realmente funciona: Pelota en Zig Zag
      Te recomiendo que revises el código fuente para aclarar cualquier duda de la explicación.

      Muchas gracias por tu participación
      Saludos

      Alejandro

      • jesus dice:

        holaa km estas me gusta mucho tus videos sola quiero saver como puedo diseñar un juego de bolas criollas porfa me da una opinion o una ayuda como empieso

  5. Sergio dice:

    Sólo una pregunta: ¿no es cierto que en HTML5 no hace falta el atributo «type» dentro de la etiqueta «script»?

    • Hola Sergio.

      Es correcto, cuando el lenguaje Script es JavaScript (por defecto), es opcional ponerle el type en HTML5.

      Lo mismo ocurre con el style, al ser CSS no es obligatorio ponerlo.

      Saludos y gracias por los comentarios.

      Damián

  6. Sergio dice:

    Ah, y perdona, pero… me parece un artículo muy muy recomendable. Gracias

  7. juan carlos dice:

    que tal, tendras algun codigo de imagne de una aguila???

  8. soledad dice:

    exelente tu aportación estas con todo en html5. felicidades!! gracias por la ayuda

  9. Enzo dice:

    Hola! Genial tu explicacion pero me surge una duda…
    Aun no existe un software que te permita hacer la animacion de una forma mas visual y rapida?
    Porque a la hora de hacer una pequeña animacion, si hay que escribir tanto codigo, creo que el tiempo a tardar es demasiado.

  10. Henderson Rojas dice:

    Alguien de ustedes sabe como hacer algo asi

    http://www.vitakids.com.ve/index.php

  11. Daniel dice:

    ¿y si quisieramos que la pelota rebotara de forma aleatoria? ¿como se podria hacer esto?
    Gracias.

    • Daniel

      No estoy seguro qué considerás un rebote aleatorio. Podría ser el movimiento en zig-zag, tal como describí en un comentario anterior. Ese es un movimiento tanto horizontal como vertical. Si estás pensando en algo que no sea previsible, habría que utilizar alguna función random para determinar la dirección inicial de la pelota.

      Saludos

  12. Erik dice:

    Hola, y si quisiera que las ‘x’ empezaran de Abajo-izquierda, en vez de arriba-derecha??
    coomo en un plano, que las ‘x’ van de izq a derecha y las ‘y’ de abajo hacia arriba?

  13. Luis-bcn dice:

    Hola estoy interesado en este canvas, soy un aficionado y novato, no entiendo mucho pero necesito que sea una imagen la que rebote es una foto panorámica en una pagina de mountainbike y lo único que he visto es esto, pero no se donde poner la foto.
    me podeis ayudar.

  14. Pedro dice:

    Muy buen post. Sigan así.

  15. koko dice:

    estoy buscando un codigo
    pueden ayudarme?

  16. Jordi dice:

    Calculando con inputs el area de las distintas figuras geometricas existentes: cuadrado, circulo, triangulo, etc. y creando con divs las diferentes figuras como se realizaria con código que al hacer click con un botón con input type=»button», etc que nos cambiara el tamaño del area y el volumen, etc y se viera que ql hacer clic en el boton por ejemplo del cuadrado y dandole valores a la base y a la altura la imagen se cambiara automaticamente????.
    Utilizando el evento de onclick de javascript y empleando CSS3 y html5.
    Como se haria, me podrias dar una solucion a ello con código.
    Gracias

  17. Lissette dice:

    como convertimos esa pelota en un triangulo ?

  18. Miguel Salinas dice:

    Gracias por compartir tu conocimiento

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*