Introducción canvas
El elemento canvas nos permite crear gráficos de forma dinámica directamente en el navegador, algo que en el pasado solo era posible mediante el uso de plugins como flash.
A lo largo de este tutorial encontraras una serie de ejercicios interactivos, que tiene como objetivo explicar de forma clara los conceptos tratados.
La etiqueta canvas
Al insertar la etiqueta <canvas>, se crea un área rectangular transparente con un tamaño por defecto de 300×150 pixeles.
El elemento cuenta con los atributos width y height que permiten cambiar su ancho y alto respectivamente.
Un atributo importante es el id, que si bien no es obligatorio, hace mas fácil el acceder al elemento mediante javascript.
Ejercicio
Crea el siguiente documento html y ábrelo en tu navegador
<!DOCTYPE html>
<html>
<head>
<title>Canvas desde cero</title>
<style>
canvas { border: 1px dotted black; }
</style>
</head>
<body>
<canvas id="canvas" width="400" height="500"></canvas>
</body>
</html>
El contexto de dibujo
El <canvas> se compone de dos partes:
- Lo que vemos en el navegador (el elemento).
- El contexto de dibujo: contiene los métodos y propiedades usados para dibujar.
Para acceder al contexto usamos el método getContext del elemento canvas, éste recibe como argumento un string que identifica el tipo de contexto que deseamos obtener, en este caso "2d" (también existe un contexto 3d).
Una vez obtenemos el contexto, podemos utilizar sus métodos para dibujar.
Obtén el contexto 2d
Llena los espacios en blanco para obtener el contexto 2d del elemento canvas
<canvas id="canvas"><canvas>
// 1) Obtén una referencia al elemento canvas (usando su id)
var canvas = document.getElementById("");
// 2) Usa el método getContext para obtener el contexto 2d
var ctx = canvas.getContext("");
// 3) Utiliza los métodos del API
ctx.fillRect(20, 20, 40, 30);
Sistema de coordenadas
El sistema de coordenadas del canvas se asemeja a un plano cartesiano, con la diferencia que el eje y aumente hacia abajo.
Ejercicio
Modifica las coordenadas para mover el punto rojo
Coordenadas(X=, Y=)
Dibujando en el canvas
Rectángulos
Existen tres métodos para dibujar rectángulos (en realidad son tres):
- fillRect(x, y, ancho, alto)
- dibuja un rectángulo con el color de relleno.
- strokeRect(x, y, ancho, alto)
- dibuja el contorno de un rectángulo.
- rect(x, y, ancho, alto)
- A diferencia de los métodos anteriores, rect solo traza el rectangulo, debemos llamar a los métodos fill y/o stroke para ver el resultado.
Experimenta
- Cambia la posición y tamaño del rectángulo.
- Dibuja solo el contorno
Rutas
Las rutas nos permiten dibujar formas complejas mediante una seria de lineas interconectadas.
¿Qué es una ruta?
¿Alguna vez jugaste a unir los puntos?
Las rutas son similares, solo que en este caso somos nosotros quienes definimos los puntos.
La creación de una ruta se divide en:
// iniciar una ruta nueva
ctx.begintPath();
// .. trazar la ruta
ctx.moveTo(10, 10);
ctx.lineTo(100, 100);
ctx.lineTo(200, 100);
// cerrar la ruta (opcional)
ctx.closePath();
// rellenar de color y/o trazar el contorno
ctx.fill();
ctx.stroke();
A continuación describiremos cada uno de estos métodos
Iniciando y cerrando una ruta
- ctx.beginPath()
- inicia una ruta nueva. Recuerda llamar este método siembre que vayas a crear una figura o pueden ocurrir cosas extrañas.
Ejercicio: Borra la linea que dice ctx.beginPath().
¿Que sucedió?
Al no iniciar una nueva ruta, todos los puntos que se crean terminan perteneciendo a la misma ruta, por lo que al usar stroke todos vuelven a ser trazados.
- ctx.closePath()
- Cierra la ruta actual mediante una linea recta entre el ultimo punto marcado y el punto inicial.
La diferencia entre usar closePath y no usarlo solo es visible al delinear (usando stroke)
ya que fill() “traza” la linea de todas formas.
- Comenta la linea del closePath
- Sustitulle closePath con el lineTo equivalente
Dibujando la ruta
una vez trazada la ruta es necesario llamar uno de los siguientes métodos con el fin de ver el resultado.
- stroke: delinea el contorno de la ruta con el color de delineado actual
- fill: rellena el interior de la ruta con el color de relleno actual
Importante
agrega ctx.fill() al final del script, luego cámbialo por ctx.stroke()
Lineas
- lineTo(x, y)
moveTo(x, y)
Si estuviéramos usando un lápiz, lineTo sería cuando rayamos y moveTo cuando levantamos el lápiz para ubicarnos en una nueva posición.
ctx.moveTo(10, 75);
ctx.lineTo(60, 75);
ctx.moveTo(110, 75);
ctx.lineTo(160, 75)
ctx.moveTo(210, 75);
ctx.lineTo(260, 75);
ctx.stroke();
Arcos
- arc(x, y, radio, angulo_inicial, angulos_final, sentido_antihorario)
- Crea un arco en entre los ángulos inicial y final. Si sentido_antihorario es true
el arco se traza entre el ángulo final e inicial
Importante
los ángulos se expresan en radianes
ctx.arc(150, 75, 70, 0, Math.PI / 3, false);
Círculos
Para crear un circulo debemos trazar un arco entre los ángulos 0 y 2π, en este caso sentido_antihorario no es relevante ya que el arco esta cerrado:
ctx.arc(x, y, radio, 0, Math.PI * 2, false);
Agregando estilo
Hasta el momento todo ha sido en blanco y negro, es momento de darle un poco de vida a nuestros dibujos.
Color
- strokeStyle
- fillStyle
- Estas dos propiedades permiten controlar el color de las lineas y el de relleno respectivamente.
Los colores pueden ser dados en cualquiera de los siguientes formatos:- hexadecimal: #fff, #ac43de.
- rgb: rgb(255, 255, 255).
- rgba: rgba(20, 40, 50, .5).
- por nombre: red, blue, orange…
Ejercicio
Dibuja una bandera
Ajustando las lineas
Existen tres atributos que controlan la forma en que se dibujan las lineas:
- lineWidth
- El ancho de la linea.
- lineCap
- La terminación de la linea (redondeada o cuadrada).
- lineJoin
- La terminación del ángulo formado al “doblar” una linea (cuadrado, redondeado, triangular)
Ejercicio Cambia las valores de las propiedades usando el formulario bajo el canvas
Sombras
Cuatro atributos controlan la forma en que se dibuja la sombra:
- shadowOffsetX
- shadowOffsetY
-
valor numérico para el desplazamiento horizontal y vertical de la sombra (puede ser negativo).
- shadowBlur
-
valor numérico que indica el grado de desenfoque.
- shadowColor
- un color.
Por defecto es completamente transparente por lo que no veras nada a menos que lo cambies.
Ejercicio: Agrega sombra a las figuras
Advertencia El dibujar sombras con blur es una operación muy costosa, así que es mejor no excedernos con su uso en las animación.
Opacidad
Si bien podemos usar un color rgba para dibujar una figura semi-transparente. cuando dibujamos una imagen o un frame de un vídeo es necesario cambiar la opacidad global.
Para esto debemos cambiar la propiedad globalAlpha el cual acepta un valor entre 0 y 1.
El estado del canvas
Todos los cambios realizados en color, sombra, tipo de linea, rotación… se preservan.
Por lo tanto, a menos que queramos aplicar el mismo estilo a todas las figuras dibujadas, es necesario revertir estos cambios.
Hacer esto de forma manual podría introducir errores (por ejemplo si olvidamos algún atributo). es por esto que existen dos métodos muy útiles:
- ctx.save()
ctx.restore()
Estos dos métodos permiten guardar el estado actual del contexto de dibujo y restaurarlo posteriormente.
Al llamar el método save, el estado actual de los atributos es guardado.
Una vez terminemos de dibujar podemos llamar el método restore, con el fin de revertir los cambios realizados.
Una operación muy común es encerrar las operaciones de dibujo de cada figura en los métodos save y restore, de esta forma podemos tener varios objetos que representan las figuras junto con sus propiedades y aplicar sus propiedades sin preocuparnos de alterar el estado de las demás.
Ejercicio
Borra la linea linea donde se usa save()
Nota: llamar a restore sin antes utilizar save, no tiene ningún efecto.
Al no guardar y restaurar el estado del contexto, el color y rotación del primer rectángulo se mantienen, afectando al segundo rectángulo.
Transformaciones
El canvas cuenta con cuatro métodos que permiten manipular el sistema de coordenadas.
Debemos recordar usar save y restore siempre que usemos alguna transformación en el canvas,
ya que es mas fácil restaurar el estado anterior del canvas que recordar realizar las operaciones
inversas en el orden correcto.
A continuación analizaremos cada uno en detalle
Trasladar
- ctx.translate(x, y)
- este método nos permite mover el origen del sistema de coordenadas
por lo general el origen se encuentra en la parte superior izquierda del canvas, la posición de todas las operaciones de dibujo se basan en este punto.
Por lo tanto la posición real en el canvas se da por la suma del origen del sistema de
coordenadas y la posición que pasamos a la operación de dibujo:
Por ejemplo:
ctx.translate(100, 100);
// la posicion real de este rectangulo es 110, 110
ctx.strokeRect(10, 10, 20, 20);
Rotar
- ctx.rotate(angulo)
- rota el sistema de coordenadas alrededor del punto de origen
Al contrario de lo que se podría pensar, la rotación se realiza con respecto al origen del sistema de coordenadas y no con respecto a cada figura.
Para girar una figura con respecto a ella misma, debemos:
- Trasladar el origen a la posición deseada
- Rotar
- Dibujar con respecto a (0, 0).
// rotar rectángulo
// por la esquina superior izquierda
ctx.save();
ctx.translate(50, 50);
ctx.rotate(Math.PI / 2);
ctx.fillRect(0, 0, 20, 20);
ctx.restore();
Ejercicio
has que el rectángulo gire por su centro
Escalar
- ctx.scale(escalaX, escalaY)
- valores mayores a 1 aumentan el tamaño.
- valores entre 0 y 1 reducen el tamaño.
- Si la escala es negativa, el sentido de las coordenadas se invierte, lo que permite por ejemplo dibujar texto al revés.
Escala las unidades usadas en los métodos de dibujo de la siguiente forma:
Experimenta: Modifica la escala usando diferentes valores
No Comments