Cómo crear animaciones de gráficos en el Canvas (HTML)
[ Este artículo está destinado a desarrolladores de Windows 8.x y Windows Phone 8.x que escriben aplicaciones de Windows Runtime. Si estás desarrollando para Windows 10, consulta la documentación más reciente ]
El elemento Canvas es una región en la que se puede dibujar dentro de tu documento HTML y en la que puedes usar JavaScript para generar gráficos como animaciones, dibujos y juegos. Este tema comienza describiendo los pasos necesarios para animar un dibujo básico con el elemento Canvas.
Requisitos previos
Este tema presupone que tú:
- Sabes crear una aplicación de la Tienda Windows básica con JavaScript que usa la plantilla Biblioteca de Windows para JavaScript.
- Comprendes los conceptos básicos de HTML y JavaScript.
Para obtener instrucciones sobre cómo crear tu primera aplicación de la Tienda Windows con JavaScript, consulta Crear la primera aplicación de la Tienda Windows con JavaScript. Para obtener instrucciones sobre el uso de la plantilla de WinJS, consulta el tema sobre cómo obtener y usar el kit de herramientas de WinJS.
Instrucciones
Paso 1: Sincronización de la animación
Usando el método requestAnimationFrame, puedes comenzar una animación si especificas una función a la que llamar (devolución de llamada) siempre que sea hora de actualizar la animación para el próximo redibujado:
requestAnimationFrame(animationFunction);
requestAnimationFrame tiene en cuenta la visibilidad de la página y la frecuencia de actualización de la pantalla para determinar cuántos fotogramas por segundo se deben asignar a la animación (es decir, llamar a animationFunction
).
Nuestro ejemplo de JavaScript dibuja un círculo animado que se mueve en espiral alrededor de un círculo de mayor tamaño.
requestAnimationFrame(draw);
Esta es nuestra animación (los resultados pueden variar; con un hardware más rápido, los círculos van a una velocidad más cercana):
Paso 2: Dibujar la imagen
Borrar el Canvas
Deberás borrar el Canvas antes de dibujar cada fotograma.
Existen varios métodos para borrar un Canvas, o partes de una imagen, como puede ser borrar ciertas áreas mediante la propiedad
globalCompositOperation
o recortando recorridos mediante el métodoclip
. La forma más sencilla de borrar un Canvas es usando el métodoclearRect
.En nuestro ejemplo, se usa el método
clearRect
para borrar todo el Canvas pero, para que sea más fácil ver los efectos de dibujar nuestra imagen, hemos convertido el métodoclearRect
en comentario. Si elimináramos la marca de comentario de esta línea de código, verías un único círculo dando vueltas en espiral alrededor de una órbita circular de mayor tamaño y su rastro se borraría antes de que se dibujara cada fotograma.// The clearRect method clears the entire canvas. context.clearRect(0, 0, 160, 160);
Guardar el estado del Canvas
Al dibujar tu imagen, es posible que cambies algunos valores de configuración como estilos o transformaciones. Si deseas usar la configuración original cada vez que empiezas a redibujar la imagen, puedes usar el método
save
.Los métodos
save
yrestore
se usan para guardar y recuperar el estado del Canvas en una pila. El estado del Canvas se compone de todos los estilos y transformaciones que se han ido aplicando. Cada vez que se llama al métodosave
, se guarda el estado actual del Canvas en la pila. El métodorestore
devuelve el último estado guardado de la pila.En nuestro ejemplo, usamos el método
save
justo antes de definir algunas transformaciones para dibujar y mover el círculo animado.// Save the canvas state. context.save();
Dibujar la imagen
Mientras se dibuja la imagen en el Canvas, puedes usar dos transformaciones para aplicar cambios a tu imagen: los métodos translate y rotate.
El método translate se usa para mover el Canvas y su origen a un punto diferente en la cuadrícula del Canvas:
translate(x, y)
Este método toma dos argumentos, x es la cantidad que se mueve el Canvas hacia la izquierda o hacia la derecha, e y es la cantidad que se mueve hacia arriba o hacia abajo.
Te recomendamos guardar el estado del Canvas antes de aplicar ninguna transformación, porque es más fácil llamar al método
restore
que tener que hacer una traslación inversa para devolver el Canvas a su estado original. El métodotranslate
te permite colocar la imagen en cualquier lugar del Canvas sin tener que ajustar manualmente las coordenadas.El método
rotate
se usa para girar el Canvas alrededor del origen actual. Este método solo tiene un parámetro y es el ángulo que gira el Canvas, medido en radianes.rotate(angle)
La rotación se mueve en el sentido de las agujas del reloj y el punto central de la rotación es siempre el origen del Canvas (la esquina superior izquierda). Para mover el punto central, deberás mover el Canvas con el método
translate
.En nuestro ejemplo, vamos a alternar algunas llamadas a los métodos
translate
yrotate
. La primera llamada al métodotranslate
centrará la animación en el Canvas.Después creamos dos conjuntos de llamadas a los métodos
rotate
ytranslate
. Las primeras llamadas a estos métodosrotate
ytranslate
producirán un pequeño círculo que se dibuja alrededor del Canvas en un gran bucle. El segundo conjunto de llamadas producirá un círculo pequeño que se dibuja en una órbita mucho más pequeña.El tamaño del Canvas está configurado en 160 píxeles de alto por 160 píxeles de ancho, así que estableceremos las coordenadas x e y del método translate igual a 80 de forma que toda nuestra animación esté centrada en el Canvas.
// centers the image on the canvas context.translate(80, 80);
Comenzamos nuestra primera llamada al método
rotate
usando el objetodate
para calcular el parámetro del métodorotate
. Este parámetro es el ángulo que se girará el Canvas.var time = new Date(); context.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
Observa que el valor que se usa para calcular
getSeconds
es 60 y el valor para calculargetMilliseconds
es 60.000.El método
translate
mueve la coordenada x que mueve el círculo giratorio alrededor del Canvas en una gran órbita.// Translate determines the size of the circle's orbit. context.translate(50, 0);
Este es el efecto de los primeros métodos
rotate
ytranslate
:Las dos llamadas siguientes a los métodos
rotate
ytranslate
crean una órbita más pequeña de círculos en bucle.// Rotate causes the circle to move in a small orbit. context.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() ); // Translate determines the size of the orbit. context.translate(0, 5);
Observa que, al calcular el ángulo de la segunda llamada al método rotate, el valor usado para calcular
getSeconds
es 6 y el valor para calculargetMilliseconds
es 6.000.Si convirtiéramos en comentarios los primeros métodos
rotate
ytranslate
, esto es lo que dibujarían nuestros segundos métodosrotate
ytranslate
:Una vez definido todo el cambio de posición, se dibuja el círculo en el Canvas.
// This draws the repositioned circle context.beginPath(); context.arc(5, 5, 4, 0, Math.PI*2, true); context.stroke();
Restaurar el estado del Canvas
En el paso b guardamos el estado del Canvas, así que ahora restablecemos el estado del Canvas para dibujar el siguiente fotograma.
// Restores the canvas to the previous state context.restore();
Ejemplos completos
Gráfico animado
Este ejemplo de JavaScript dibuja un círculo animado que se mueve con un movimiento en espiral alrededor de un círculo de mayor tamaño.
window.onload = init;
// As an optimization, make "context" a global variable that is only set once.
var context;
function init(){
context = document.getElementById('canvas').getContext('2d');
window.requestAnimationFrame(draw);
} // init
function draw() {
// Save the canvas state.
context.save();
// context.clearRect(0, 0, 160, 160);
// centers the image on the canvas
context.translate(80, 80);
// Rotate moves the spiraling circle around the canvas in a large orbit.
var time = new Date();
context.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
// Translate determines the location of the small circle.
context.translate(50, 0);
// Rotate causes the circle to spiral as it circles around the canvas.
context.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
// determines the size of the loop
context.translate(0, 5);
// This draws the circle
context.beginPath();
context.arc(5, 5, 4, 0, Math.PI*2, true);
context.stroke();
// Restores the canvas to the previous state
context.restore();
window.requestAnimationFrame(draw);
} // draw
Este es un ejemplo de unas hojas de estilo CSS que crea un borde negro alrededor de un elemento Canvas.
/* style the canvas element with a black border. */
canvas { border: 1px solid black; }
Este archivo HTML crea un elemento Canvas y usa archivos JavaScript y CSS externos.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="myJavascript.js"></script>
<link Rel="stylesheet" Href="myStyle.css" Type="text/css">
</head>
<body>
<canvas id="canvas" width="160" height="160" />
</body>
</html>