Canvas HTML5: animaciones I



       En el artículo anterior vimos como usar el canvas para dibujar figuras sencillas. Se pueden hacer dibujos mucho más complejos, pero la gran utilidad del canvas es hacer animaciones, así que vamos a ver las bases de la animación en canvas.

       Necesitamos una función de pintado que se llame sucesivamente para ir pintando cada frame de la animación. Veremos métodos mejores, pero por ahora vamos a usar lo más básico, un temporizador:

setTimeout(pintar,100);

       Esta será la última línea de la función pintar, que se llama a si misma cada 100 milisegundos, así que pintamos 10 veces por segundo, por lo que veremos claramente los saltos de la animación y no será fluida, pero para el ejemplo nos sirve.

       Lo que vamos a animar es un rectángulo haciendo que se mueva un poco a los lados, con una función de traslación (muy similar a las que vimos para CSS3):

ctx.translate(t,0);

       Donde t será cuanto desplazamos el cuadrado, y será una variable que incrementemos o reduzcamos en cada pintada. Con esto nos quedaría una animación como la siguiente:




       El resultado no es el buscado, porque el canvas dibuja sobre el frame anterior, así que no vemos al rectángulo moverse, sino que parece que se está haciendo más grande. Nos falta borrar el frame anterior antes de dibujar el siguiente. Eso lo podemos hacer asignando el ancho del canvas al ancho del canvas:

canvas.width=canvas.width;

       El código completo y el ejemplo funcionando queda:

<style>
#canvas22{
  width: 500px;
  height: 300px;
  margin: 0 auto;
  display:block;
  border: 1px solid #000;
}
</style>

<canvas id="canvas22" width="500" height="300"></canvas>

<script>
  var t=0;
  var derecha=true;
  var canvas=document.getElementById("canvas22");
  var ctx = canvas.getContext("2d");
  function pintar(){
    canvas.width=canvas.width;
    if (derecha){
       t+=10;
       if (t>100){
         derecha=false;
       }
    }else{
       t-=10;
       if (t<-100){
         derecha=true;
       }
     }
     ctx.translate(t,0);
     ctx.fillStyle = "rgb(200,200,0)";
     ctx.fillRect(150, 100, 200, 100);
     setTimeout(pintar,100);
  }</script>