Tutorial de HTML5
Tutorial de HTML5
Qué es HTML 5
En el artículo anterior publicado en DesarrolloWeb.com, "El futuro del desarrollo web: HTML 5"
explicamos las razones por las que es verdaderamente importante esta nueva versión del lenguaje
de marcación HTML y vimos quiénes son los que están llevando a cabo su especificación.
Ahora convendría explicar qué es exactamente HTML 5, ya que no es simplemente una nueva
versión del lenguaje de marcación HTML, sino una agrupación de diversas especificaciones
concernientes a el desarrollo web. Es decir, HTML 5 no se limita sólo a crear nuevas etiquetas,
atributos y eliminar aquellas marcas que están en desuso o se utilizan inadecuadamente, sino que
va mucho más allá.
Así pues, HTML 5 es una nueva versión de diversas especificaciones, entre las que se encuentran:
• HTML 4
• XHTML 1
• DOM Nivel 2 (DOM = Document Objetc Model)
A la par, HTML 5 pretende proporcionar una plataforma con la que desarrollar aplicaciones web
más parecidas a las aplicaciones de escritorio, donde su ejecución dentro de un navegador no
implique falta de recursos o facilidades para resolver las necesidades reales de los desarrolladores.
Para ello se están creando unas APIs que permitan trabajar con cualquiera de los elementos de la
página y realizar acciones que hasta hoy era necesario realizar por medio de tecnologías
accesorias.
Estas API, que tendrán que ser implementadas por los distintos navegadores del mercado, se
están documentando con minuciosidad, para que todos los Browsers, creados por cualquier
compañía las soporten tal cual se han diseñado. Esto se hace con la intención que no ocurra lo que
viene sucediendo en el pasado, que cada navegador hace la guerra por su parte y los que acaban
pagándolo son los desarrolladores y a la postre los usuarios, que tienen muchas posibilidades de
acceder a webs que no son compatibles con su navegador preferido.
Resulta que HTML 5 está formado por muchos módulos distintos, cuyo grado de especificación
está en niveles dispares. Por tanto, muchas de las características de HTML 5 están ya listas para ser
implementadas, en un punto de desarrollo que se encuentra cercano al que finalmente será
presentado. Otras muchas características están todavía simplemente en el tintero, a modo de
ideas o borradores iniciales.
De hecho, las versiones más nuevas de casi todos los navegadores, incluido el polémico Internet
Explorer 8, implementan algunas de las características de HTML 5. Claro que, para que una web se
vea bien en todos los sistemas, hay que utilizar sólo aquellas partes que funcionan en todos los
navegadores, por lo que a día de hoy, pocas son las utilidades realmente disponibles del lenguaje,
si queremos hacer un sitio web compatible. No obstante, en el peor de los casos, podemos
empezar a usar a nivel experimental estas características, aunque sólo sea para frotarnos las
manos en espera de incorporarlas realmente en nuestras prácticas de desarrollo habituales.
• Estructura del cuerpo: La mayoría de las webs tienen un formato común, formado por
elementos como cabecera, pie, navegadores, etc. HTML 5 permite agrupar todas estas
partes de una web en nuevas etiquetas que representarán cada uno de las partes típicas
de una página.
• Etiquetas para contenido específico: Hasta ahora se utilizaba una única etiqueta para
incorporar diversos tipos de contenido enriquecido, como animaciones Flash o vídeo.
Ahora se utilizarán etiquetas específicas para cada tipo de contenido en particular, como
audio, vídeo, etc.
• Canvas: es un nuevo componente que permitirá dibujar, por medio de las funciones de un
API, en la página todo tipo de formas, que podrán estar animadas y responder a
interacción del usuario. Es algo así como las posibilidades que nos ofrece Flash, pero
dentro de la especificación del HTML y sin la necesidad de tener instalado ningún plugin.
Puedes conocer más sobre este nuevo elemento en el manual de canvas que estamos
creando en DesarrolloWeb.com
• Bases de datos locales: el navegador permitirá el uso de una base de datos local, con la
que se podrá trabajar en una página web por medio del cliente y a través de un API. Es
algo así como las Cookies, pero pensadas para almacenar grandes cantidades de
información, lo que permitirá la creación de aplicaciones web que funcionen sin necesidad
de estar conectados a Internet.
• Web Workers: son procesos que requieren bastante tiempo de procesamiento por parte
del navegador, pero que se podrán realizar en un segundo plano, para que el usuario no
tenga que esperar que se terminen para empezar a usar la página. Para ello se dispondrá
también de un API para el trabajo con los Web Workers.
• Aplicaciones web Offline: Existirá otro API para el trabajo con aplicaciones web, que se
podrán desarrollar de modo que funcionen también en local y sin estar conectados a
Internet.
• Geolocalización: Las páginas web se podrán localizar geográficamente por medio de un
API que permita la Geolocalización.
• Nuevas APIs para interfaz de usuario: temas tan utilizados como el "drag & drop"
(arrastrar y soltar) en las interfaces de usuario de los programas convencionales, serán
incorporadas al HTML 5 por medio de un API.
• Fin de las etiquetas de presentación: todas las etiquetas que tienen que ver con la
presentación del documento, es decir, que modifican estilos de la página, serán
eliminadas. La responsabilidad de definir el aspecto de una web correrá a cargo
únicamente de CSS.
Como se puede ver, existirán varios API con los que podremos trabajar para el desarrollo de todo
tipo de aplicaciones complejas, que funcionarán online y offline. Quizás se entienda mejor por qué
HTML 5 es un proyecto tan ambicioso y que está llevando tanto tiempo para ser elaborado.
El elemento canvas permite especificar un área de la página donde se puede, a través de scripts,
dibujar y renderizar imágenes, lo que amplía notablemente las posibilidades de las páginas
dinámicas y permite hacer cosas que hasta ahora estaban reservadas a los desarrolladores en
Flash, con la ventaja que para usar canvas no será necesario ningún plugin en el navegador, lo que
mejorará la disponibilidad de esta nueva aplicación.
En este artículo y los siguientes pretendemos dar una introducción a canvas, para los lectores de
DesarrolloWeb.com interesados en conocer de cerca esta nueva utilidad de HTML 5. Al menos
esperamos dar a conocer las posibilidades del canvas y ofrecer algunos ejemplos que se puedan
probar ya en los navegadores más modernos.
Compatibilidad de canvas
El canvas se desarrolló inicialmente por Apple para su navegador Safari y luego fue utilizado y
estandarizado por la organización WHATWG para incorporarlo a HTML 5. Posteriormente también
ha sido adoptado por navegadores como Firefox y Opera.
Por lo que respecta a Chorme, es un navegador que utiliza el mismo motor de renderizado que
Safari, por lo que también soporta el elemento Canvas.
De entre los navegadores más habituales sólo nos queda por soportar canvas el siempre polémico
Internet Explorer. La última versión del navegador en el momento de escribir este artículo,
Internet Explorer 8, no soporta canvas con funciones nativas, pero existen diversos proyectos y
plugins que pueden ampliar las funcionalidades del navegador para dar soporte a este nuevo
elemento del HTML 5. Por ejemplo, existe el proyecto Explorer Canvas en el que se ha preparado
un plugin para que Explorer soporte el dibujo 2d que permite canvas.
Sin embargo, aunque en diversos frentes se ha comenzado a utilizar Canvas, la falta de soporte de
Explorer hace que todavía no sea muy recomendable su incorporación a las aplicaciones web, ya
que la mayoría de los usuarios, que utilizan explorer, no podrían ver las partes de la página donde
se utiliza canvas. Esta situación se espera que cambie durante los próximos meses o años, puesto
que la incorporación de canvas al HTML 5 ya es una realidad e Internet Explorer más tarde o
temprano tendrá que dar soporte esta utilidad en su navegador, si no quiere que se descarte su
utilización por parte de los usuarios que deseen acceder a los servicios web más avanzados.
Actualmente algunas de las aplicaciones más novedosas para para la web utilizan ya canvas para
su funcionamiento, donde se puede destacar Bespin, un editor de código de Mozilla, o Google
Wave. En la entrada de la Wiki sobre Canvas podemos encontrar diversos enlaces a sitios web con
ejemplos de uso de este elemento del HTML 5.
En los siguientes artículos veremos ejemplos de uso de canvas y explicaremos cómo podemos
utilizar nosotros mismos esta nueva herramienta del HTML 5.
Para comenzar realizaremos un ejemplo de dibujo de dos rectángulos con distintos colores, que
realizaremos utilizando el un par de funciones del API de dibujo en canvas mediante Javascript.
Claro que el elemento canvas tiene muchas cosas que debemos conocer para ir soltándonos en su
manejo, pero al menos podremos ver una primera prueba para ir abriendo boca.
El ejemplo se basa en dos partes, primero una en la que colocaremos un lienzo canvas en un lugar
de nuestra página, con la etiqueta HTML "CANVAS" y luego otra parte en la que dibujaremos
dentro de ese elemento los rectángulos con programación Javascript. Sobra decir que harán falta
unos conocimientos al menos básicos de Javascript para poder trabajar con el canvas.
El elemento tiene apertura y cierre y entre medias podemos escribir un texto que será lo que vean
los usuarios que entren con navegadores que no soporten la etiqueta CANVAS.
Atributo id:
Para asignarle un nombre único y luego referirnos a este canvas desde Javascript.
Otros atributos se pueden colocar de manera opcional, como por ejemplo style, para indicar
atributos de hojas de estilo para definir el aspecto del lienzo.
Inicialmente el canvas está en blanco y cuando queremos pintar sobre él tenemos que acceder al
contexto de renderizado del canvas, sobre el que podremos invocar distintos métodos para
acceder a las funciones de dibujo. El proceso simplificado sería el siguiente:
Primero con el método getElementById() obtengo el elemento de la página que se pasa como
parámetro, que es el canvas. Luego accedo al contexto 2D del canvas, que es el que tiene varios
métodos que sirven para dibujar en el lienzo. Por último puedo ejecutar tantos métodos como
desee sobre el contexto del canvas para pintar elementos en el lienzo.
Como decía, estas sentencias Javascript no son compatibles con todos los navegadores, por lo que
habrá que hacer unas comprobaciones básicas, para saber si ejecutar o no las distintas
instrucciones de dibujo.Veamos este código, un poco más elaborado, que hace las
comprobaciones necesarias para no hacer nada en el caso que el navegador no sea compatible
con canvas.
Ahora sólo falta una última cosa, que es ejecutar estas acciones sólo cuando la página esté cargada
por completo y lista para recibirlas. Esto lo conseguimos con la el evento onload del body de la
página:
<body onload="funcionDeDibujo()">
Claro que tendremos que crear la funcionDeDibujo() con el código anterior para operar con el
canvas.
O bien podemos utilizar este otro recurso para asignar el evento directamente desde un script
Javascript:
window.onload = function(){
//instrucciones de dibujo en canvas
}
<html>
<head>
<title>Probando canvas</title>
<script>
window.onload = function(){
//Recibimos el elemento canvas
var elemento = document.getElementById('micanvas');
//Comprobación sobre si encontramos un elemento
//y podemos extraer su contexto con getContext(), que indica compatibilidad con canvas
if (elemento && elemento.getContext) {
//Accedo al contexto de '2d' de este canvas, necesario para dibujar
var contexto = elemento.getContext('2d');
if (contexto) {
//Si tengo el contexto 2d es que todo ha ido bien y puedo empezar a dibujar en el canvas
//Comienzo dibujando un rectángulo
contexto.fillRect(0, 0, 150, 100);
//cambio el color de estilo de dibujo a rojo
contexto.fillStyle = '#cc0000';
//dibujo otro rectángulo
contexto.fillRect(10, 10, 100, 70);
}
}
}
</script>
</head>
<body>
El lienzo producido por canvas tendrá unas dimensiones indicadas con los atributos width y height
en la etiqueta CANVAS. Por tanto, la esquina superior izquierda será el punto (0,0) y la esquina
inferior derecha el punto definido por (width-1,height-1), osea, el punto máximo de coordenadas
marcado por su anchura y altura.
Nota: Hemos indicado que el punto de la esquina inferior derecha es (width-1,height-1) porque las
coordenadas comienzan en (0,0), luego la coordenada final en anchura y altura será 1 menos el
tamaño máximo de width y height definido en la etiqueta CANVAS. Por ejemplo, si la anchura es
50 y la altura es 100, entonces las coordenadas van desde (0,0) hasta (49,99).
Podemos ver el siguiente diagrama para tener una idea exacta de las dimensiones y coordenadas
en un canvas.
Cualquier punto dentro del canvas se calcula con la coordenada (x,y), siendo que la x crece según
los pixel a la derecha y la y con los pixel hacia abajo.
Para dibujar cualquier tipo de forma en el canvas necesitaremos posicionarla con respecto a las
coordenadas que acabamos de ver. En el ejemplo del artículo anterior, vimos que para dibujar un
rectángulo necesitamos varios valores:
Los dos primeros parámetros eran las coordenadas x e y de la esquina superior izquierda del
rectángulo. Los dos últimos parámetros son los valores de anchura y altura del mismo.
Pero hay otras formas que se pueden dibujar en un canvas que requieren el uso de métodos con
un poco más elaborados que el dibujo de un rectángulo. Lo veremos más adelante.
Vimos que parte del código Javascript necesario era para realizar las comprobaciones pertinentes
a fin de asegurarnos que el navegador es compatible con canvas cuando queremos extraer el
contexto del canvas antes de empezar a dibujar. En este ejemplo realizaremos una función para
resumir estas tareas que podremos utilizar a lo largo de este manual.
Podremos invocar esta función y evaluar su resultado para saber si se obtuvo o no el contexto del
canvas.
En este ejemplo vamos a dibujar un par de rectángulos, uno azul y otro amarillo. Ya vimos en el
anterior ejemplo cómo se hacían formas rectangulares y también aprendimos a cambiar el color
de la forma. Para mostrar otra de las posibilidades del canvas vamos a mostrar cómo hacer un
color semitransparente.
Si nos fijamos, cuando se cambió el color a amarillo se especificó el color con RGBA, esto significa
que estamos indicando también el canal Alpha, que indica el grado de transparencia desde 0
(totalmente transparente) a 1 (totalmente opaco).
Aclarmos de cualquier forma que todas estas funciones de dibujo las explicaremos con
detenimiento más adelante.
<html>
<head>
<title>Canvas segundo ejemplo</title>
<script>
//Recibe un identificador del elemento canvas y carga el canvas
//Devueve el contexto del canvas o FALSE si no ha podido conseguise
function cargaContextoCanvas(idCanvas){
var elemento = document.getElementById(idCanvas);
if(elemento && elemento.getContext){
var contexto = elemento.getContext('2d');
if(contexto){
return contexto;
}
}
return FALSE;
}
window.onload = function(){
//Recibimos el elemento canvas
var contexto = cargaContextoCanvas('micanvas');
if(contexto){
//Si tengo el contexto
//cambio el color de dibujo a azul
contexto.fillStyle = '#6666ff';
//dibujo un rectángulo azul
contexto.fillRect(10,10,50,50);
//cambio el color a amarillo con un poco de transparencia
contexto.fillStyle = 'rgba(255,255,0,0.7)';
//pinto un rectángulo amarillo semitransparente
contexto.fillRect(35,35,50,50);
}
}
</script>
</head>
<body>
El ejemplo puede verse en marcha en una página aparte, pero tener en cuenta que hace falta
disponer de compatibilidad con canvas en vuestro navegador.
Como ya se explicó anteriormente, canvas es un elemento sobre el que dibujamos por medio de
sentencias en el lenguaje de programación Javascript. Sin embargo, por el momento todos los
navegadores no son compatibles con este nuevo componente, por lo que tendremos que hacer
comprobaciones para no ejecutar en los navegadores ninguna instrucción que pueda dar errores
por problemas de compatibilidad. Esto también se explicó en el artículo Ejemplo de dibujo con el
API de canvas y además se profundizó un poco en anterior artículo a este, cuya lectura también
recomendamos, Entender el lienzo de canvas.
En este artículo vamos a explicar cómo podemos utilizar las funciones fillRect() y strokeRect() para
dibujar rectángulos en la página y además vamos a implementar una pequeña interacción por
medio de un enlace, que al pulsarlo ejecutará una función Javascript para borrar el contenido del
canvas con la función clearRect().
Función fillRect()
Esta función, perteneciente al objeto contexto de un elemento canvas, sirve para dibujar
rectángulos rellenos de color. Recibe cuatro parámetros, con este esquema:
fillRect(x,y,anchura,altura)
Esto dibuja un rectángulo cuya esquina superior izquierda está en el punto (x,y) y cuyas
dimensiones son altura x anchura.
El color de relleno no lo especificamos en la propia función, sino que es el color que se tenga
configurado en ese momento como color de relleno, que se indica con la propiedad fillStyle del
contexto del canvas, asignando por ejemplo el RGB de un color.
Nota:Como vimos en el artículo Entender el lienzo de canvas, antes de ejecutar este método,
necesitamos acceder al contexto de un canvas, para luego invocar al método sobre ese objeto.
Esto lo vamos a dar por sabido aquí, y recomendamos la lectura del señalado artículo para las
personas que tengan dudas.
Esto dibujaría una serie de rectángulos, comenzando en la posición (0,0) y continuando con
posiciones siempre de 10 píxeles de distancia en ambas coordenadas: (10,10), (20,20) ... Acabando
en la coordenada (100,100). Todos los rectángulos serán de 5 píxeles de alto y ancho, luego
realmente son cuadrados.
Función strokeRect()
Esta función sirve para dibujar simplemente la silueta de un rectángulo, es decir, sólo su borde. El
esquema de parámetros es el siguiente:
strokeRect(x,y,anchura,altura)
for (i=100;i>=0;i-=10){
contexto.strokeRect(i,100-i,5,5);
}
Con el código anterior también dibujamos una serie de cuadrados en el canvas, aunque en esta
ocasión sólo la silueta sin estar rellenos de color, de 5 píxeles de anchura y altura y con distintas
coordenadas que producimos al hacer el bucle for.
De manera similar, para definir el color del borde del rectángulo, utilizamos la propiedad
strokeStyle del objeto del contexto del canvas, a la que podemos asignar el valor RGB que
deseemos para el borde de los cuadrados o aquello que vayamos a dibujar en el canvas.
Función clearRect()
Esta función nos sirve para borrar áreas rectangulares de un canvas y hacerlas totalmente
transparentes o sin contenido gráfico. Funciona de manera similar a los rectángulos:
clearRect(x,y,anchura,altura)
El color aquí no importa mucho, porque es simplemente el color del fondo del contenedor HTML
donde hayamos colocado el canvas.
<html>
<head>
<title>Canvas rectángulos</title>
<script>
//Recibe un identificador del elemento canvas y carga el canvas
//Devueve el contexto del canvas o FALSE si no ha podido conseguise
function cargaContextoCanvas(idCanvas){
var elemento = document.getElementById(idCanvas);
if(elemento && elemento.getContext){
var contexto = elemento.getContext('2d');
if(contexto){
return contexto;
}
}
return FALSE;
}
window.onload = function(){
//Recibimos el elemento canvas
var contexto = cargaContextoCanvas('micanvas');
if(contexto){
//Si tengo el contexto
function borrar_parcial(){
var contexto = cargaContextoCanvas('micanvas');
if(contexto){
//clearRect(x,y,width,height) borra un área rectangular del canvas dejándola transparente
contexto.clearRect(60,0,42,150);
}
}
</script>
</head>
<body bgcolor="#ffff99">
</body>
</html>
Nota: Internet Explorer, al menos hasta la versión 8 no soporta canvas, luego no será compatible
con este ejemplo.
En el evento window.onload definimos una serie de instrucciones que dibujarán una serie de
rectángulos justo cuando la página haya terminado de cargarse.
Con la función borrar_parcial() simplemente borramos un área del canvas y a esta función se llama
por medio del evento onclick del enlace que hay en la parte de abajo del código.
Esperamos que con estas indicaciones y el anterior ejemplo se haya podido entender
correctamente el modo de dibujar rectángulos en un elemento Canvas del HTML 5. En futuros
artículos veremos cómo dibujar otros tipos de formas. Quizás lo más complicado para
desarrolladores sin experiencia sea la necesidad de trabajar con el lenguaje de programación
Javascript, pero recordamos que en DesarrolloWeb.com puedes encontrar una serie de manuales
de Javascript que están incluso al alcance de personas que no hayan programado nunca.
Para trabajar con color en los elementos canvas tenemos varias posibilidades, pero de momento
vamos a aprender a modificar el color con el que se rellena o se dibuja trazados. Como vimos
anteriormente, al dibujar rectángulos, podemos elegir entre dibujar sólo su contorno o dibujarlos
rellenos de color (y luego veremos que esto es así con otros tipos de caminos). Ahora veremos que
existen dos atributos del contexto del canvas que sirven para definir el color de relleno y el color
de trazado a la hora de dibujar rectángulos u otros caminos.
ctx.fillStyle = '#990000';
Suponiendo que tenemos el objeto contexto de un canvas en la variable ctx, con la anterior línea
estamos solicitando al elemento canvas que la próxima vez que se rellene el color se haga en rojo
oscuro.
ctx.strokeStyle = '#000099';
Con esa línea estamos marcando que el color de trazado sea azul oscuro. Por lo cual, la próxima
vez que se haga un trazado la línea será de ese color.
Si lo deseas, antes de continuar la lectura, puede ser interesante ver el ejemplo en marcha.
Veamos antes que nada un par de funciones para conseguir un color aleatorio en Javascript. La
primera nos ofrece un número aleatorio y la segunda, que se apoya en la primera, nos sirve para
generar una cadena que especifica un color.
function aleatorio(inferior,superior){
numPosibilidades = superior - inferior
aleat = Math.random() * numPosibilidades
aleat = Math.floor(aleat)
return parseInt(inferior) + aleat
}
function colorAleatorio(){
return "rgb(" + aleatorio(0,255) + "," + aleatorio(0,255) + "," + aleatorio(0,255) + ")";
}
Ahora vamos a mostrar otra función para dibujar el lienzo de un canvas, rellenando de cuadraditos
con colores aleatorios:
function cuadradosAleatorios(){
for(i=0; i<300; i+=10){
for(j=0; j<250; j+=10){
contexto.fillStyle = colorAleatorio();
contexto.fillRect(i,j,10,10)
}
}
}
Como se puede ver, tenemos un bucle anidado, que realiza la tarea. En cada iteración se obtiene
un color aleatorio y luego se pinta un rectángulo con ese color. La función utiliza una variable
global llamada "contexto", que es el contexto del canvas sobre el que estamos dibujando.
Ahora para acabar vamos a ver la función que se encargará de inicializar el contexto del canvas y
definir la ejecución periódica de la función cuadradosAleatorios() para generar la animación.
window.onload = function(){
//Recibimos el elemento canvas
contexto = cargaContextoCanvas('micanvas');
if(contexto){
//Si tengo el contexto, defino la función periódica
setInterval("cuadradosAleatorios(contexto)", 200);
}
}
Todo esto junto hace que consigamos una animación en el canvas, pues se invoca a la función
cuadradosAleatorios() cada 200 milisegundos, lo que genera dibujos aleatorios distintos cada poco
tiempo.
La única función que tiene cambios con respecto al ejemplo anterior es cuadradosAleatorios():
function cuadradosAleatorios(){
for(i=0; i<300; i+=10){
for(j=0; j<250; j+=10){
contexto.strokeStyle = colorAleatorio();
contexto.strokeRect(i,j,5,5)
}
}
}
En canvas existen diversas funciones que nos pueden servir para dibujar siluetas a nuestro antojo,
que se tienen que utilizar de manera complementaria. El proceso pasa por situarse en un punto
del lienzo, luego definir cada uno de los puntos por los que pasa nuestro camino y luego pintar de
color dentro, o simplemente dibujar la línea que pasaría por todos esos puntos. En este artículo
veremos cómo rellenar de color todo el área que queda definida por un camino.
Veamos para empezar un resumen de algunas de las funciones disponibles para hacer caminos, las
que que utilizaremos durante el presente artículo.
Función beginPath()
Esta función sirve para decirle al contexto del canvas que vamos a empezar a dibujar un camino.
No tiene ningún parámetro y por si sola no hace ninguna acción visible en el canvas. Una vez
invocada la función podremos empezar a dibujar el camino añadiendo segmentos para
completarlo con las diferentes funciones de caminos.
Nota: Las funciones beginPath() y siguientes en realidad son métodos del objeto de contexto del
canvas. Este objeto que mantiene el contexto del canvas lo tenemos que extraer nosotros por
medio de Javascript, a partir del elemento canvas donde deseemos dibujar. Cómo trabajar y
extraer el contexto de un canvas fue ya explicado en el artículo Ejemplo de dibujo con el API de
canvas.
Según las pruebas realizadas, podríamos iniciar un camino sin utilizar antes beginPath(), puesto
que el efecto a primera vista es el mismo que si no lo invocamos (entiendo que el navegador lo
invoca por nosotros al empezar a utilizar funciones de caminos en canvas). No obstante, debe ser
recomendable hacer las cosas correctamente e invocarlo antes de comenzar un camino.
Función moveTo()
Sirve para mover el puntero imaginario donde comenzaremos a hacer el camino. Esta función no
dibuja nada en si, pero nos permite definir el primer punto de un camino. Llamar esta función es
como si levantásemos el lápiz del lienzo y lo trasladásemos, sin pintar, a otra posición.
Recibe como parámetro los puntos x e y donde ha de moverse el puntero para dibujo. Para saber
cuál es el punto donde deseamos movernos (x,y), Recordar que el eje de coordenadas del canvas
es la esquina superior izquierda.
Función lineTo()
Esta función provoca que se dibuje una línea recta, desde la posición actual del puntero de dibujo,
hasta el punto (x,y) que se indique como parámetro. El método lineTo(), por tanto es como si
posáramos el lápiz sobre el lienzo en la posición actual y arrastrásemos, dibujando una línea recta,
hasta el punto donde se definió al invocar el método.
La posición actual del camino la podemos haber indicado previamente con un moveTo(), o donde
hayamos terminado una línea dibujada anteriormente. Si no se indicó antes una posición de
nuestro puntero de dibujo, lineTo() no dibuja ninguna línea, sino que se tendrá en cuenta las
coordenadas enviadas como parámetro para posicionar tan solo el puntero de dibujo allí. Dicho de
otra manera, si no se dijo dónde empezar el dibujo, o no se ha dibujado ningún otro segmento en
el camino anteriormente, lineTo() será equivalente a moveTo().
Función fill()
Este método del contexto del canvas sirve para rellenar de color el área circunscrita por un
camino. Para rellenar de color un camino, el camino tendría que estar cerrado, por lo que, si no lo
está, automáticamente se cerrará con una línea recta hasta el primer punto del camino, es decir,
donde comenzamos a dibujar. Sin embargo, si durante los distintos segmentos del camino nos
dejamos algún segmento abierto, no se pintará nada.
Como decimos, si no llegamos a cerrar el camino, el método fill() lo cerrará por nosotros, pero
podríamos utilizar explícitamente el método closePath() para hacerlo nosotros (closePath() lo
explicaremos en futuros artículos).
ctx.beginPath();
ctx.moveTo(50,5);
ctx.lineTo(75,65);
ctx.lineTo(50,125);
ctx.lineTo(25,65);
ctx.fill();
Como se puede ver, iniciamos un camino con beginPath(). Luego hacemos un moveTo() para
indicar el punto donde comenzar el camino. Posteriormente dibujamos varias líneas a diversos
puntos del canvas, para acabar invocando al método fill(), con lo que rellenaremos de color el
camino.
Fijarse que el camino no se había llegado a cerrar. Por lo que fill() lo cerrará por nosotros con una
línea al primer punto donde comenzamos el dibujo.
Nota: Para ejecutar estas líneas de código necesitaremos una instancia del objeto contexto del
canvas, para invocar todos los métodos sobre él. El objeto del canvas lo tenemos en la variable
"ctx" en el código del ejemplo. En el código completo del ejercicio podremos ver la función que se
podría utilizar para obtener el contexto.
Código completo del ejemplo de camino
A continuación podemos encontrar el código completo de este ejemplo de construcción de un
camino con el elemento Canvas del HTML 5.
<html>
<head>
<title>Canvas Caminos</title>
<script>
//La ya conocida función para cargar el contexto de un canvas
function cargaContextoCanvas(idCanvas){
var elemento = document.getElementById(idCanvas);
if(elemento && elemento.getContext){
var contexto = elemento.getContext('2d');
if(contexto){
return contexto;
}
}
return FALSE;
}
window.onload = function(){
//Recibimos el elemento canvas
var ctx = cargaContextoCanvas('micanvas');
if(ctx){
ctx.beginPath();
ctx.moveTo(50,5);
ctx.lineTo(75,65);
ctx.lineTo(50,125);
ctx.lineTo(25,65);
ctx.fill();
}
}
</script>
</head>
<body>
<canvas id="micanvas" width="150" height="150">
Accede a este script con un navegador que acepte canvas del HTML 5
</canvas>
</body>
</html>
Para acabar, podemos ver el ejemplo en marcha en una página aparte.
En el presente artículo veremos dos nuevas funciones útiles en la creación de caminos, que son
closePath(), para cerrar un camino y stroke(), para dibujar el camino realizado mediante una línea.
Las dos funciones, como cualquier otra función de dibujo en el lienzo de canvas, son métodos del
objeto contexto del canvas, que se debe obtener a partir del elemento canvas con las
correspondientes funciones de Javascript, tal como vimos anteriormente en este manual. Veremos
estas nuevas funciones para dibujo de caminos con un ejemplo, pero antes podemos explicarlas
detalladamente.
Función closePath()
Sirve para cerrar un camino, volviendo a su punto inicial de dibujo. Recordemos que el camino
tiene un punto inicial en el que nos situamos para comenzar el dibujo, con moveTo(). Luego vamos
dibujando segmentos en el camino por medio de líneas que nos llevan a otros puntos del lienzo.
Pues closePath() sería como dibujar una línea recta desde el punto donde se haya quedado el
camino al punto inicial donde empezamos a construirlo. El método closePath() no recibe ningún
parámetro.
Función stroke()
Con el método stroke() podemos dibujar una línea por todo el recorrido del camino que hayamos
creado por medio de sus distintos segmentos. Es similar al método fill(), explicado en el artículo
anterior, con la diferencia que fill() rellenaba de color y stroke() tan solo dibuja la silueta. Además,
en el caso de fill() se necesitaba tener el camino cerrado, por lo que se cerraba automáticamente
si no lo habíamos hecho y stroke() realmente puede estar discontinuada, puesto que sólo es una
línea lo que se dibuja y no un área.
ctx.beginPath();
ctx.moveTo(1,1);
for (i=1;i<100;i+=5){
if((i%2)!=0){
ctx.lineTo(i+5,i);
}else{
ctx.lineTo(i,i+5);
}
}
ctx.lineTo(1,i);
ctx.closePath();
ctx.stroke();
Nota:Primero cabe advertir de nuevo que para ejecutar ese código necesitamos una variable que
hemos llamado "ctx" que contiene el contexto del canvas, que es sobre el que invocaremos los
distintos métodos para dibujar en el canvas.
En el script comenzamos el camino con beginPath(), luego con moveTo(1,1) nos situamos en el
punto donde deseamos comenzar el dibujo. A continuación realizamos un bucle for para dibujar
diversas líneas en diversas coordenadas.
Acabamos haciendo una última línea con lineTo() y después un closePath() para que se dibuje una
línea final hasta el punto de inicio del camino, que cerrará la silueta realizada. Con stroke()
hacemos que se dibuje una línea pasando por todos los segmentos que completan el camino
dibujado.
ctx.beginPath();
ctx.moveTo(1,1);
for (i=1;i<100;i+=5){
if((i%2)!=0){
ctx.lineTo(i+5,i);
}else{
ctx.moveTo(i,i+5);
}
}
ctx.stroke();
Ejemplo completo de dibujo de líneas con caminos en canvas
Para todos los interesados, colocamos a continuación el código completo de este ejemplo.
<html>
<head>
<title>Canvas Caminos con stroke</title>
<script>
//Recibe un identificador del elemento canvas y carga el canvas
//Devueve el contexto del canvas o FALSE si no ha podido conseguise
function cargaContextoCanvas(idCanvas){
var elemento = document.getElementById(idCanvas);
if(elemento && elemento.getContext){
var contexto = elemento.getContext('2d');
if(contexto){
return contexto;
}
}
return false;
}
window.onload = function(){
//Recibimos el elemento canvas
var ctx = cargaContextoCanvas('micanvas');
if(ctx){
ctx.beginPath();
ctx.moveTo(1,1);
for (i=1;i<100;i+=5){
if((i%2)!=0){
ctx.lineTo(i+5,i);
}else{
ctx.lineTo(i,i+5);
}
}
ctx.lineTo(1,i);
ctx.closePath();
ctx.stroke();
}
</script>
</head>
<body>
<br>
<br>
</body>
</html>
En el presente artículo veremos las siguientes variantes de un camino con la forma de hexágono
regular:
Realmente es un mismo ejercicio con varias variantes que esperamos pueda darnos alguna pista
adicional sobre el dibujo en el elemento canvas del HTML 5. Podemos ver una imagen con los
cuatro ejemplos de caminos que haremos a continuación:
Para rellenar de color un camino utilizamos la el método fill() del contexto del canvas, que antes
de rellenar de color hace un cierre automático del camino. De esta manera, aunque no se haya
completado el camino hasta cerrarlo, al invocar ctx.fill() esta función lo cerrará por nosotros.
No obstante, para adornar un poco más el ejemplo, hemos optado por cambiar el color de relleno
del hexágono, por medio de la propiedad fillStyle del objeto contexto del canvas.
Como veremos, el camino es exactamente igual que los anteriores, con la diferencia que para
dibujar sólo la línea del contorno del camino se utiliza el método stroke() del objeto contexto de
canvas, en lugar de usar fill() que hace los caminos con relleno de color.
El camino es el mismo, pero antes de llamar a stroke() para dibujar la línea, hacemos un
closePath() para cerrar el camino. Para añadir algún interés adicional al camino, hemos utilizado
un color distinto para la línea del contorno, que se consigue en esta ocasión con la propiedad
strokeStyle del objeto contexto del canvas.
Hasta aquí llega esta práctica de caminos en Canvas del HTML 5, con distintas variantes a partir de
los mismos puntos del camino.
Si lo deseas, puedes ver una página donde se muestran los cuatro ejemplos de caminos vistos en
este artículo.
En el presente ejemplo estamos haciendo varios caminos en un mismo canvas y además, vamos a
rellenar de colores distintos cada uno de los caminos, lo que nos vendrá bien para seguir
practicando. La idea de este artículo es que nos podamos familiarizar un poco más con la práctica
de abrir caminos, cerrarlos y volver a abrir otros caminos. Además, podemos ver que con un
mismo camino también podemos pintar en dos partes distintas del lienzo, trasladando el puntero
de dibujo pero sin pintar.
Nota: Lo cierto es que este código está incompleto, pues le falta la función cargaContextoCanvas()
que ya se ha explicado anteriormente en el artículo Entender el lienzo de canvas.
En ese código estamos realizando dos caminos distintos sobre un mismo canvas. El primer camino
está separado en el código del segundo y los dos comienzan con un beginPath(). En cada camino
hacemos un moveTo() para colocar el puntero de dibujo en las coordenadas deseadas.
Luego se hace el closePath() para cerrar el camino, completándolo con una línea recta desde el
último punto hasta el punto desde donde comenzamos el caminio. Pero como se puede ver en
ejemplo, la llamada al método closePath() es opcional, pues estos dos caminos se rellenan de color
con fill() y este método requiere que el camino esté cerrado. Por eso, si el camino no se cerró
explícitamente con closePath(), con la llamada a fill() se hace implícitamente.
Otra cosa interesante es el cambio de color que hacemos en el segundo camino con la propiedad
fillStyle del objeto canvas, en la línea:
ctx.fillStyle = '#ff8800';
Es por ello que, el cambio de color con la propiedad strokeStyle, aunque se haga en el medio del
código, afecta a todo el trazado, pues es el mismo camino.
Hemos de admitir que estos dos ejemplos no significan un claro avance con respecto a lo que ya
habíamos relatado en el manual, pero nunca está de más hacer ejemplos prácticos. Además, hay
muchas cosas que merece la pena practicar para entender bien cómo se realizan. En el siguiente
artículo explicaremos nuevas técnicas para hacer líneas curvas y no sólo líneas rectas como hasta
ahora.
El método que podemos dibujar para hacer un arco es arc(), que invocamos sobre el objeto el
contexto del canvas. Este método requiere unos cuantos parámetros para poder invocarlo y
especificar las características del arco que se desea hacer y lo cierto es que no resulta del todo
trivial porque hay que conocer algunas fórmulas matemáticas para el trabajo con circunferencias.
Así que tendremos que refrescar algunos conocimientos que pueden haberse olvidado del periodo
de enseñanza media.
Nota: Igual que los caminos, una vez creados, podemos decidir si queremos rellenarlos de color,
mediante el método fill() o bien dibujar solamente el contorno, con el método stroke(). Todas
estas cosas sobre caminos y demás se pueden aprender en el Manual del trabajo con Canvas.
• Los parámetros x, y corresponden con las coordenadas del centro del arco.
• El parámetro radio es el número de píxeles que tiene el arco como radio.
• Por su parte angulo_inicio y angulo_final son los ángulos donde comienza y acaba el radio.
Están tomados como si el eje de la horizontal tuviese el ángulo cero.
• Sentido_contrario_del_reloj es un parámetro boleano, donde true significa que el trazo va
desde un ángulo de inicio al de fin en el sentido contrario de las agujas del reloj. False
indica que ese camino es en dirección contraria.
La verdad es que todos los parámetros son bastante sencillos de entender, pero el ángulo de inicio
y fin no se indican en grados, como podríamos suponer, sino en radianes. Para el que no se
acuerde, se puede hacer un paso de grados a radianes atendiendo a la siguiente fórmula:
Radianes = número_PI x (grados/180)
Para convertir grados en radianes podríamos utilizar la siguiente línea de código Javascript:
Nota: Math.PI es el famoso número PI (3.1416). En Javascript, a partir de la clase Math, tenemos
acceso a esa constante, así como diversas funcines matemáticas. Ver las notas sobre la clase Math.
Entender los radianes
Para comprender los gradianes de una manera más visual, así como la referencia sobre el eje X,
que serían los cero grados, se puede ver la siguiente imagen:
• 0 Radianes serían cero grados y es el punto marcado por 0PI, en el eje de las X y a la
derecha del centro de la circunferencia.
• 0.5 PI Radianes serían 90 grados el punto del eje de las Y abajo del centro.
• 1 PI Radianes es media circunferencia, 180 grados.
• 1.5 PI Radianes sería el equivalente a 270 grados
• 2 PI Radianes son los 360 grados de la circunferencia completa y correspondería con el
mismo punto que los cero grados.
Así pues, para hacer un círculo completo con centro en (50, 50) de 20 píxeles de radio, podríamos
utilizar un código como este:
contextoCanvas.arc(50, 50 ,20 , 0, Math.PI*2, false);
El primer camino tiene dos arcos concéntricos, uno con radio mayor y el segundo con un radio
menor. Este primer camino comienza en el radio mayor y se puede ver una línea gris que hemos
puesto, con unas flechas, para poder reconocer la dirección que lleva el camino.
De todos modos podéis ver el código fuente del ejercicio, que se puede ver en marcha de una
página aparte.
En este caso vamos a revisar un tipo de curva llamada Cuadrática, que nos sirve bien para hacer
curvas sencillas, no necesariamente arcos de una circunferencia, con un único punto de inflexión.
Por intentar explicarlo con palabras de manera entendible, podríamos decir que las curvas
cuadráticas permiten expresar una única curvatura entre dos puntos. Para expresarlas tenemos un
punto inicial, un punto final de la curva y un punto que define la tendencia de la curvatura.
Las curvas cuadráticas son un tipo concreto de curvas Bezier, es decir, una manera de expresar
matemáticamente una curva, similar a las Bezier pero más simplificada. Mientras que en las curvas
Bezier tenemos dos puntos para definir la tendencia de la curva, al principio y el fin de la misma,
en las curvas cuadráticas sólo tendremos un punto.
Nota: No hemos visto todavía las mencionadas curvas Bezier, pues son más complejas que las
curvas cuadráticas. Es por eso que las veremos más adelante.
quadraticCurveTo(pcx, pcy, x, y)
Este método recibe cuatro valores, que corresponden con dos puntos del lienzo. Insisto en que el
punto inicial ya está implícito en el contexto del canvas, con la posición dada del puntero de dibujo
antes de comenzar la curva cuadrática. Luego, el punto (pcx, pcy) es el lugar "imaginario" al que
tendrería la curvatura de la línea. El punto (x,y) sería el final de la curva.
Una manera sencilla de entender este método sería ver la siguiente imagen:
1. El primero, marcado con color morado, es la posición del puntero de dibujo al iniciar la
curva cuadrática. Ese punto no lo definimos al hacer la llamada al método
quadraticCurveTo() porque ya está implícito en el contexto del canvas. En cualquier caso
se puede cambiar con una llamada a moveTo() como hemos visto en artículos anteriores.
2. El segundo punto, marcado con color rojo, es la tendencia de la curva cuadrática. Ese
punto decimos que es imaginario porque no aparece en la curva. Simplemente sirve para
definir cómo será la curvatura. Se define con los parámetros pcx, pcy.
3. El tercer punto, dibujado en verde, es el final de la curva, definido por los parámetros x, y.
Como se puede ver, aparte de la curva cuadrática tenemos otras líneas rectas en este dibujo, que
luego se rellena de color con fill(). Nos da el resultado una forma parecida a una hoja, que se
puede ver en el ejemplo en marcha.
En el siguiente artículo podremos ver otro ejemplo para hacer curvas cuadráticas más avanzado.
Rectángulos con esquinas redondeadas en
canvas, interactivo con Mootools
Vamos a mostrar un nuevo ejemplo de dibujo de caminos en canvas un poco más avanzado.
Crearemos una página con un canvas que tendrá un rectángulo con esquinas redondeadas y una
interfaz de usuario para que se pueda configurar el radio del redondeado de las esquinas.
Es un ejemplo un poco avanzado porque mezclamos varias tecnologías, pues no sólo tenemos que
pintar en el canvas, sino también responder a acciones del usuario para alterar el dibujo.
Por un lado tenemos que saber hacer dibujos en canvas con curvas cuadráticas. De hecho, este
ejemplo de trabajo en canvas del HTML 5 nos ayudará a observar un poco más la utilidad de las
curvas cuadráticas.
Para que el usuario pueda definir el radio de las curvas en las esquinas del rectángulo vamos a
colocar una interfaz de tipo "slider" creada con el framework Javascript Mootools, que permite
cambiar el valor del radio arrastrando un control. Además habrá un campo de texto para cambiar
este radio escribiendo cualquier otro valor directamente.
Para saber mejor qué es lo que vamos a crear, recomendamos echar un vistazo a la página del
ejemplo.
function roundedRect(ctx,x,y,width,height,radius){
ctx.beginPath();
ctx.moveTo(x,y+radius);
ctx.lineTo(x,y+height-radius);
ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
ctx.lineTo(x+width-radius,y+height);
ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
ctx.lineTo(x+width,y+radius);
ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
ctx.lineTo(x+radius,y);
ctx.quadraticCurveTo(x,y,x,y+radius);
ctx.stroke();
}
Simplemente hace un rectángulo en la posición x,y con anchura y altura dadas por medio de los
parámetros width y height y un último parámetro radius para especificar el radio de la curvatura
en la esquina redondeadas.
Ahora podríamos hacer un rectángulo redondeado con la siguiente llamada:
function actualizaRadioRectangulo(radio){
radio = parseInt(radio)
if (isNaN(radio)) {
radio = 0;
}
var ctx = cargaContextoCanvas('micanvas');
if(ctx){
ctx.clearRect(0,0,150,150);
roundedRect(ctx, 10, 10, 130, 110, radio);
}
}
Ahora podemos ver el campo de texto para cambiar el radio de las esquinas manualmente,
escribiendo cualquier otro valor dentro del mismo.
Como se puede ver, tiene definido un evento para actualizar el radio del rectángulo cuando el
usuario pulsa una tecla en el campo de texto.
Ese componente slider está en la distribución Mootools que se llama "more" y tenemos que
descargarla por separado en la propia página de descarga de Mootools, accediendo mediante el
enlace que pone "More Builder". Allí tenemos que seleccionar por lo menos el componente
"Slider" y los paquetes requeridos se seleccionarán automáticamente.
Nota: Recordemos que el "More" de Mootools son una serie de scripts para crear interfaces de
usuario avanzadas. Se descarga por separado del "Core", que es el framework fundamental. Por
supuesto, para poder implementar los componentes del "More" se necesita tener disponible el
"Core". En principio dicen en la página de Mootools que para ejecutar cualquier componente del
"More" es necesario haber descargado el "Core" completo.
Así pues, para la parte del slider tenemos que incluir los scrips "Core" y "More"
Luego podríamos tener un HTML como este para producir el contenedor del slider:
Ahora podemos ver el script Mootols para generar dinámicamente el componente a partir de
estos elementos HTML.
window.addEvent("domready", function(){
var miSlider = new Slider("slidercontenedor", "slidercontrol",{
'range': [0,55],
'steps': 55,
'initialStep': 20,
onChange: function(lugar){
actualizaRadioRectangulo(lugar);
$("valor").set("html", lugar);
}
});
});
De todos modos, para referencia podemos ver a continuación el código completo de este creador
dinámico e interactivo de rectángulos redondeados.
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script src="mootools-1.2.4-core-yc.js" type="text/javascript"></script>
<script src="mootools-1.2.4.2-more.js" type="text/javascript"></script>
<title>Curvas cuadráticas</title>
<script>
//Recibe un identificador del elemento canvas y carga el canvas
//Devueve el contexto del canvas o FALSE si no ha podido conseguise
function cargaContextoCanvas(idCanvas){
var elemento = document.getElementById(idCanvas);
if(elemento && elemento.getContext){
var contexto = elemento.getContext('2d');
if(contexto){
return contexto;
}
}
return FALSE;
}
function actualizaRadioRectangulo(radio){
radio = parseInt(radio)
if (isNaN(radio)) {
radio = 0;
}
var ctx = cargaContextoCanvas('micanvas');
if(ctx){
ctx.clearRect(0,0,150,150);
roundedRect(ctx, 10, 10, 130, 110, radio);
}
}
window.onload = function(){
//Recibimos el elemento canvas
var ctx = cargaContextoCanvas('micanvas');
if(ctx){
roundedRect(ctx, 10, 10, 130, 110, 20);
}
}
</script>
<script>
window.addEvent("domready", function(){
var miSlider = new Slider("slidercontenedor", "slidercontrol",{
'range': [0,55],
'steps': 55,
'initialStep': 20,
onChange: function(lugar){
actualizaRadioRectangulo(lugar);
$("valor").set("html", lugar);
}
});
});
</script>
</head>
<body>
El modelo que propone Bezier es un tipo de función matemática para definir curvas complejas en
función de varios valores. Es una técnica utilizada en el dibujo técnico, que surgió inicialmente en
el mundo de la aeronáutica y el diseño de coches y que se hizo bastante popular a raíz de su
utilización en varios programas de diseño, como el conocido Photoshop. Las curvas Bezier se crean
por medio de una fórmula matemática que permite especificar y evaluar trazados curvos que
podrían tener más de un punto de inflexión.
Como vemos, se tienen que especificar coordenadas de tres puntos, de una manera similar a la
que conocimos en las curvas cuadráticas.
Nota:Las curvas cuadráticas un tipo determinado de curvas Bezier, lo que ocurre es que en las
curvas Bezier utilizamos dos puntos de tendencia de la curva, para el principio y el final de la
misma, mientras que en las curvas cuadráticas sólo se utilizaba uno. Para aclarar este punto
recomendamos echar un vistazo a las explicaciones sobre curvas cuadráticas.
En la siguiente imagen se puede ver un diagrama sobre los puntos que se utilizan para definir una
curva Bezier.
Como podemos ver, el método bezierCurveTo() tiene 6 parámetros que corresponden con las
coordenadas de 3 puntos, pero en la imagen se utilizan hasta 4 puntos para definir la curva Bezier,
pues el punto de incicio de la curva ya estaba en el contexto del canvas. Así que, atendiendo a la
anterior imagen, estos serían los puntos necesarios para componer la curva Bezier:
1. El primer punto, marcado con color morado, es el punto inicial de la curva. Este punto no
se tiene que definir, pues ya está implícito en el contexto del canvas, en el lugar donde
estaba el puntero de dibujo al llamar al método bezierCurveTo().
Nota: Al dibujar cualquier segmento de un camino tenemos definido siempre de
antemano el punto inicial de ese segmento del camino, pues es el lugar donde está el
puntero de dibujo. Nosotros podríamos cambiar ese puntero de dibujo, para cambiar el
primer punto de la curva, con una llamada al método moveTo().
2. El segundo punto, que se ha marcado de color verde, es la tendencia de la primera parte
de la curva, que se indica con los parámetros pc1x, pc1y.
3. El tercero, marcado de color rojo, es la tendencia de la segunda parte de la curva, que se
indica con los parámetros pc2x, pc2y.
4. Finalmente, tenemos el punto final de la curva, marcado en color gris, que se indica con
los parámetros x,y.
Ahora podemos complicar un poco más ese ejemplo para crear otros caminos con curvas Bezier,
con la particularidad de que vamos a rellenarlos con colores semitransparentes.
Nota: Nosotros asignamos colores de relleno para los caminos con la propiedad fillStyle del objeto
contexto del canvas. Podemos asignar un color con un código RGB de una manera que ya
conocemos:
ctx.fillStyle = "#ccccff";
Pero aparte, también podemos indicar colores con valores RGB en decimal, de manera similar a
como se hace en CSS, e incluso podemos asignar valores RGBA (con canal alpha para la
transparencia).
ctx.fillStyle = 'rgba(100,230,100,0.3)';
ctx.beginPath();
ctx.fillStyle = 'rgba(100,230,100,0.3)';
ctx.moveTo(0,90);
ctx.bezierCurveTo(90,7,110,15,140,30);
ctx.bezierCurveTo(130,55,140,65,145,70);
ctx.bezierCurveTo(180,45,190,55,200,95);
ctx.lineTo(200,150);
ctx.lineTo(0,150);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgba(230,230,100,0.3)';
ctx.moveTo(50,150);
ctx.bezierCurveTo(90,7,110,15,160,10);
ctx.bezierCurveTo(130,105,140,135,200,35);
ctx.lineTo(200,150);
ctx.lineTo(0,150);
ctx.fill();
Creando esos otros caminos el ejemplo queda como se puede ver en este enlace
http://www.desarrolloweb.com/articulos/ejemplos/html5/bezier-curve.html.
Usar imágenes en el Canvas
Una de las cosas más interesantes que podremos hacer cuando dibujamos en el lienzo del
elemento canvas es importar y mostrar directamente el contenido de archivos gráficos externos,
es decir, usar imágenes GIF, JPG o PNG dentro de los dibujos que realizamos con canvas. En este
artículo veremos cómo realizar este punto, aunque adelantamos que es bastante fácil.
Las imágenes provenientes de archivos gráficos las podemos crear con nuestro editor preferido y
hacer fácilmente gráficos bastante creativos y vistosos, o editar a partir de fotos creadas con
nuestra cámara. Luego las podemos incluir en el Canvas y así conseguir que nuestros trabajos
tengan una mejor calidad que si dibujamos a mano con las funciones Javascript del API de Canvas.
Con un poco de creatividad y algo de código Javascript, podremos hacer composiciones basadas
en varias imágenes "pegadas" en el lienzo, o utilizar imágenes de fondo sobre las que luego
pintamos con Javascript para destacar cosas. Como podemos usar cualquier tipo de archivo
gráfico, mientras que esté soportado por el navegador, las posibilidades son enormes.
Referencia: Para entender este artículo debes haber seguido las explicaciones del Manual del
elemento Canvas publicadas en DesarrolloWeb.com.
drawImage(objeto_imagen, x, y)
Enviamos tres parámetros, el primero es el objeto Javascript de la imagen que se desea incluir en
el lienzo. Los dos siguientes son las coordenadas donde situar la imagen, siendo (x,y) el punto
donde se colocará la esquina superior izquierda de la imagen.
Como decía, este método pertenece al objeto del canvas, por lo que antes de poder invocarlo
debemos haber obtenido el contexto del canvas, tal como hemos aprendido anteriormente en el
Manual de Canvas para cualquier otro tipo de dibujo.
Este objeto de imagen lo podemos obtener de varias maneras, pero de momento vamos a
aprender a generarlo dinámicamente con una instrucción Javascript.
img.src = 'logo-grande.jpg';
Esto hace que en el objeto Image se cargue la imagen que está en el archivo 'logo-grande.jpg' y
como no hemos especificado ningún directorio en la ruta, se supone que ese archivo está en la
misma carpeta que el archivo HTML donde esté ese código Javascript.
Una vez tenemos el objeto imagen, podríamos pintarlo en un canvas por medio de la función
drawImage(). Sería algo parecido a esto:
Pero atención, porque este código tiene un detalle: la imagen no se dibujará en el canvas a no ser
que esté previamente cargada en el navegador.
<html>
<head>
<title>Imágenes en Canvas</title>
<script language="javascript">
function cargaContextoCanvas(idCanvas){
var elemento = document.getElementById(idCanvas);
if(elemento && elemento.getContext){
var contexto = elemento.getContext('2d');
if(contexto){
return contexto;
}
}
return FALSE;
}
window.onload = function(){
//Recibimos el elemento canvas
var ctx = cargaContextoCanvas('micanvas');
if(ctx){
//Creo una imagen conun objeto Image de Javascript
var img = new Image();
//indico la URL de la imagen
img.src = 'logo-desarrolloweb.gif';
//defino el evento onload del objeto imagen
img.onload = function(){
//incluyo la imagen en el canvas
ctx.drawImage(img, 10, 10);
}
}
}
</script>
</head>
<body>
</body>
</html>
La idea es experimentar con el dibujo en Canvas por medio de una nueva práctica y a la vez
repasar todos los modos que existen de obtener una imagen por medio de Javascript, que ya
explicamos en el artículo Distintas maneras de acceder a objetos Image Javascript.
1.- Traerse una imagen que hay en la página: por medio del método getElementById(), enviando
como parámetro el identificador de la etiqueta IMG de la imagen deseada.
2.- A través del Array de images: También de una imagen que haya en la página, en una etiqueta
IMG. Al array accedemos con el índice de la imagen según orden de aparición en el código HTML.
3.- Creando nuestro objeto Image: Que es la forma con la que trabajamos en el artículo anterior. Y
por tanto no vamos a repetir las explicaciones.
5.- Acceder a el diseño dibujado en otro canvas: para mostrar en un canvas el contenido de otro,
como si fuera una imagen.
Este quinto y último método permite algunas aplicaciones interesantes, como mostrar un un
canvas una miniatura de lo que hay en otro canvas.
Se podrá ver que en realidad se crean dos canvas. Uno sólo lo creamos para poder copiarlo en otro
canvas.
window.onload = function(){
document.images[1].src =
'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkc
uO4lmNVindo7qyrIXiGBYAOw==';
}
</script>
</head>
<body>
<h2>Canvas que estoy creando con una serie de imágenes</h2>
<canvas id="micanvas" width="500" height="400">
Tu navegador no soporta canvas.
</canvas>
<p>
<div style="display: none;">
<h2>Cosas que pongo aquí para acceder desde Javascript</h2>
<img src="canvas-html5.png" id="im1">
<img src="logo-grande.jpg">
<p>
<canvas id="canvas2" width="150" height="150">
Recicla tu navegador!!
</canvas>
</div>
</body>
</html>
En futuros artículos mostraremos cómo podemos alterar la forma de las imágenes dinámicamente,
para mostrarlas en el canvas con algunos cambios.
El método es bien simple y consiste en invocar al método que dibuja las imágenes, drawImage(),
enviando distintos juegos de parámetros. Anteriormente ya habíamos trabajado con este método,
que como debemos saber, pertenece al objeto contexto de un canvas. En el pasado lo llamamos
simplemente enviándole la imagen y las coordenadas donde había que colocarla. Ahora vamos a
ver los otros dos modos de invocarlo, por medio de parámetros adicionales, que nos faltan por
conocer. El primero de los modos de invocación permite escalar una imagen y el segundo
recortarla y escalarla en un mismo paso.
Las nuevas dimensiones de la imagen a dibujar pueden ser las que deseemos. Pueden incluso no
ser proporcionales a las dimesiones actuales, en ese caso el navegador estirará la imagen o la
achatará para adaptarla a la anchura y altura que hayamos indicado.
Este método dibujará la imagen en la posición definida por las coordenadas (posX, posY) y con la
anchura y altura dadas en los últimos dos parámetros.
Este ejemplo dibuja la misma imagen tres veces, dos de ellas está escalada a distintas dimensiones
y la última está a tamaño natural (sin redimensionar).
Entre los parámetros, "imagen" sigue siendo el objeto imagen Javascript que queremos pintar.
Todos los parámetros siguientes los podemos entender a la vista de la siguiente imagen:
Podemos ver a continuación el código de un ejemplo que realiza el recorte y escalado de una
imagen.
Este ejemplo dibuja una imagen un par de veces. Primero recorta un área de la imagen original y la
escala, por el método de drawImage() que acabamos de relatar. Luego dibuja la imagen original,
sin recortar ni escalar, y la coloca al lado de la otra, en el mismo canvas.
Para acabar, dejamos un enlace, de modo que puedas ver este segundo ejemplo de trabajo con
imágenes en canvas.