Contexto


La API Canvas de HTML5 está revolucionando los gráficos y las visualizaciones en la Web. Alimentado por JavaScript, la API Canvas de HTML5 permite a los desarrolladores Web crear visualizaciones y animaciones directamente en el navegador sin Flash. La API Canvas de HTML5 se está convirtiendo rápidamente en el estándar de gráficos e interactividad en línea.

Explicación


14.1 Dibujando en un lienzo

Si deseas dibujar elementos gráficos en tu página Web en lugar de incluirlos como una imagen externa con el elemento “img”, entonces usa el elemento “canvas” en su marcado:

<canvas id="mycanvas"></canvas>

Alternativamente, siempre puedes crear dinámicamente un elemento canvas y anexarlo a la página y luego usar CSS para colocarlo donde lo necesites:

var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
document.body.appendChild(mycanvas);

Para dibujar en el elemento de canvas, primero obtén una referencia al contexto del elemento canvas y luego emite comandos de dibujo contra esa referencia, como se muestra a continuación:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<link rel="stylesheet" type="text/css" href="styles/application.css">
<script src="js/prefixfree.js"></script>

</head>
<body>
<script>
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
mycontext.beginPath();
mycontext.moveTo(10, 10);
// Dibuja una linea de (10,10) a (35,35)
mycontext.lineTo(35, 35);
mycontext.strokeStyle = "#000";
mycontext.stroke(); // Dibuja la linea
mycontext.beginPath();
mycontext.arc(35, 35, 10, 0, Math.PI * 2, true); // dibuja un circulo
mycontext.fillStyle = "#f00";
mycontext.fill(); // llena el circulo con solido
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

El API de canvas

Estos son algunos de los comandos de dibujo más utilizados en Canvas API:

Haz clic en cada elemento.

Inicia una definición de segmento de ruta para ser utilizada por una operación de representación, stroke() o fill().
Cierra la ruta agregando un segmento de línea desde el final de la ruta de regreso al comienzo del camino.
Mueve el punto de registro para la siguiente operación de dibujo relativo.
Crea una ruta de línea desde el punto de registro actual a (x, y).
Crea una ruta rectangular donde (x, y) es una esquina y la diagonal opuesta a la esquina es (x + ancho, y + alto)
Crea una ruta de arco circular (hasta un círculo completo), donde (x, y) es el centro del arco, y el arco comienza y termina en los ángulos dados (en radianes) y se mueve en el sentido horario o antihorario.

 

Completa el segmento de camino definido más recientemente.
Trazo (renderizar, hacer visible) el segmento de ruta más reciente.
Dibuja una imagen en el área del lienzo.
Despeja una porción rectangular del lienzo de (x, y) a (x + ancho, y + alto)
Establece los atributos de color/estilo para trazos o rellenos, respectivamente.

 

Usando la transparencia

Supón que deseas dejar parte del elemento canvas transparente para mostrar contenido por debajo.

El elemento canvas es, por defecto, transparente, lo que significa que se mostrará a través de cualquier contenido que esté apilado debajo de él. Esto significa que puedes controlar qué píxeles son transparentes o no, simplemente por lo que dibujas en el elemento canvas.

Si posicionas un círculo rojo (como en el ejemplo anterior) sobre la parte superior de un texto, las partes del elemento de lienzo que no dibuja el círculo son transparentes, mostrando el texto desde abajo.

Además de la transparencia de cualquier píxel que aún no se haya dibujado en el elemento de lienzo, un píxel puede tener una transparencia parcial utilizando el canal alfa del color utilizado para dibujar el píxel. La transparencia parcial significa que lo que el usuario ve para cada píxel es la combinación de qué color se encuentra en esa ubicación debajo del elemento del lienzo, combinado con el color parcial que se muestra para ese píxel en el elemento del lienzo.

Si el círculo rojo sobre el texto de la página anterior se dibujara con un color parcialmente transparente, aparecería como se muestra en el ejemplo siguiente.

El color parcialmente transparente no sólo es útil para el contenido que aparece en la página debajo del elemento canvas, sino también para el contenido que ya está dibujado en el elemento canvas en sí mismo:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<link rel="stylesheet" type="text/css" href="styles/application.css">
<script src="js/prefixfree.js"></script>

</head>
<body>
<script>
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
// Transparancia
mycontext.beginPath();
mycontext.arc(40, 40, 25, 0, Math.PI * 2, true); // draw a circle
mycontext.closePath();
mycontext.fillStyle = "#f00";
mycontext.fill(); // Llena el circulo solido
mycontext.beginPath();
mycontext.arc(70, 40, 25, 0, Math.PI * 2, true); // Dibuja un circulo
mycontext.closePath();
mycontext.fillStyle = "rgba(0,0,255,0.75)";
mycontext.fill(); // Llena el circulo
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

En el fragmento de código anterior se dibuja un círculo azul parcialmente transparente que se superpone a la parte de un círculo rojo. La porción de círculos que se superponen producirá el color púrpura debido a la mezcla del azul con el rojo.

 

Configuración de las dimensiones del lienzo

Si deseas especificar explícitamente el ancho y el alto de tu elemento canvas, que son diferentes de las dimensiones predeterminadas, agrega los atributos de ancho y alto y sus valores correspondientes a tu elemento canvas:

<canvas id="mycanvas" width="200" height="200"></canvas>

También puedes cambiar el ancho y/o alto de tu elemento canvas con JavaScript. Si deseas cambiar el ancho o alto (píxeles para renderizar) en tu elemento canvas, entonces debes cambiar los atributos del elemento canvas (no las propiedades de estilo CSS de ancho y alto, como podrías suponer).

mycanvas.setAttribute("width", "200"); 
mycanvas.setAttribute("height", "200");

 

Creando un degradado

Supón que deseas crear degradados y otros estilos de dibujo.

 

Cada vez que se renderiza una ruta al elemento canvas, el color y el estilo de ese dibujo se recogen de los estilos de trazo y relleno establecidos actualmente.

Por ejemplo, para variar la forma en que los segmentos de línea se dibujan en las rutas, puedes controlar los estilos de trazo con lineWidth, lineCap y lineJoin, como se muestra en:

mycontext.lineWidth = "12";
mycontext.lineJoin = "round";
mycontext.moveTo(20, 20);
mycontext.lineTo(50, 50);
mycontext.lineTo(20, 70);
mycontext.stroke();

Para variar lo que está pintado dentro de los caminos que dibuja, puedes controlar los estilos de relleno para crear degradados o patrones de imágenes, como se muestra en:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<!--<link rel="stylesheet" type="text/css" href="styles/application.css">-->
<script src="js/prefixfree.js"></script>
</head>
<body>
<script>
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
// Transparancia
var lingrad = mycontext.createLinearGradient(20, 20, 40, 60);
lingrad.addColorStop(0.3, "#0f0");
lingrad.addColorStop(1, "#fff");
mycontext.fillStyle = lingrad;
mycontext.moveTo(20, 20);
mycontext.lineTo(50, 50);
mycontext.lineTo(20, 70);
mycontext.closePath();
mycontext.fill();
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

Extracción de imágenes externas en un lienzo dibujo

Supón que tienes una imagen existente (gráfico, ícono, foto, etc.) en un archivo externo que deseas colocar en un elemento de lienzo, de modo que puedas manipularlo o embellecerlo con los comandos de dibujo de lienzo API.

Primero, carga la imagen en cuestión utilizando una etiqueta “img” en tu marcado y obtén una referencia a ella, o crea un elemento Imagen de forma dinámica en tu código JavaScript:

A continuación, una vez que se cargue la imagen, dibuja la imagen en un elemento canvas:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<!--<link rel="stylesheet" type="text/css" href="styles/application.css">-->
<script src="js/prefixfree.js"></script>
</head>
<body>
<script>
// My context
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
// cambiamos las dimensiones
mycanvas.width = 800;
mycanvas.height = 800;
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");

var img = new Image();
img.onload = function () {
// note: we're calling against the "2d" context here
mycontext.drawImage(img, 0, 0); // draw the image at (0,0)
};
img.src = "Flores.jpg";
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

Establecer transformaciones de color

Supón que tienes un dibujo de lienzo existente al que deseas aplicar una transformación de color (como escala de grises o invertir).

La API Canvas proporciona un comando getImageData (...), que toma todos los datos de color de píxeles del elemento canvas y te los entrega en una matriz: var drawing = mycontext.getImageData(0, 0, 200, 200);

Una vez que hayas capturado los datos de la imagen, puedes manipular esos datos usando cualquier transformación que desees y luego volver a escribir esos datos de imagen en el elemento canvas.

Para dibujar en escala de grises, el algoritmo más simple es tomar el promedio de los componentes de color rojo, verde y azul, y dividir por 3 ese valor promedio:

        var avg;
// skip 4 entries (1 px) at a time
for (var i = 0; i < drawing.data.length; i = i + 4) {
avg = (drawing.data[i] + drawing.data[i + 1] + drawing.data[i + 2]) / 3;
drawing.data[i] = drawing.data[i + 1] = drawing.data[i + 2] = avg;
}

Para invertir el dibujo en color, el algoritmo más simple es tomar cada valor de componente de color, restarlo de 255 y volver a establecer ese valor de color:

// skip 4 entries (1 px) at a time
for (var i = 0; i < drawing.data.length; i = i + 4) {
drawing.data[i] = 255 - drawing.data[i]; // invert red
drawing.data[i + 1] = 255 - drawing.data[i + 1]; // invert green
drawing.data[i + 2] = 255 - drawing.data[i + 2]; // invert blue
}

Ahora que los datos se han modificado, simplemente volvemos a escribir los datos en el elemento canvas, utilizando el comando putImageData (...):

mycontext.putImageData(drawing, 0, 0);

Ejemplo:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<!--<link rel="stylesheet" type="text/css" href="styles/application.css">-->
<script src="js/prefixfree.js"></script>
</head>
<body>
<script>
// My context
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
// cambiamos las dimensiones
mycanvas.width = 200;
mycanvas.height = 200;
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
// Transparancia
mycontext.beginPath();
mycontext.arc(40, 40, 25, 0, Math.PI * 2, true); // draw a circle
mycontext.closePath();
mycontext.fillStyle = "#f00";
mycontext.fill(); // Llena el circulo solido
mycontext.beginPath();
mycontext.arc(70, 40, 25, 0, Math.PI * 2, true); // Dibuja un circulo
mycontext.closePath();
mycontext.fillStyle = "rgba(0,0,255,0.75)";
mycontext.fill(); // Llena el circulo
var drawing = mycontext.getImageData(0, 0, 200, 200);
var avg;
// Salta 4 entradas (1 px) a la vez
for (var i = 0; i < drawing.data.length; i = i + 4) {
avg = (drawing.data[i] + drawing.data[i + 1] + drawing.data[i + 2]) / 3;
drawing.data[i] = drawing.data[i + 1] = drawing.data[i + 2] = avg;
}
// Salta 4 entradas (1 px) a la vez
for (var i = 0; i < drawing.data.length; i = i + 4) {
drawing.data[i] = 255 - drawing.data[i]; // invertir rojo
drawing.data[i + 1] = 255 - drawing.data[i + 1]; // invertir verde
drawing.data[i + 2] = 255 - drawing.data[i + 2]; // invertir rojo
}
// Coloca la imagen de vuelta en (0,0)
mycontext.putImageData(drawing, 0, 0);
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

Trabajando con transformaciones geométricas

¿Deseas aplicar algunas transformaciones a tus comandos de dibujo, como escalado, rotación, sesgado, entre otros?

La API de canvas proporciona varios comandos para transformar tus acciones de dibujo de canvas:

Haz clic en cada elemento.

Mover/sesgar la ubicación del punto de origen para el sistema de coordenadas de (0,0) a (x, y).
Escala las unidades del sistema de coordenadas en las direcciones x e y, rota de forma independiente (ángulo).
Gira el sistema de coordenadas alrededor del punto de origen (0,0), el ángulo (sentido horario) se especifica en radianes.

 

Cuando comienzas a combinar transformaciones múltiples, a menudo es más fácil administrar el estado del elemento de canvas en una pila, donde simplemente puedes revertir un nivel para deshacer todas las transformaciones (y otro estado, como las configuraciones de estilo/color) con un comando.

La API de canvas proporciona dos comandos para administrar la pila de estado:


save()



restore()


Ejemplo:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<!--<link rel="stylesheet" type="text/css" href="styles/application.css">-->
<script src="js/prefixfree.js"></script>
</head>
<body>
<script>
// My context
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
// cambiamos las dimensiones
mycanvas.width = 200;
mycanvas.height = 200;
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
mycontext.save(); // salvamos el estado actual del canvas
mycontext.translate(10, 10); // movemos el punto a (10,10)
mycontext.arc(0, 0, 10, 0, Math.PI * 2, true); // dibujamos un circulo
mycontext.stroke();
mycontext.restore();
mycontext.save();
mycontext.rotate(Math.PI / 4); // rotamos 45 grados
mycontext.moveTo(0, 0);
mycontext.lineTo(10, 0);
mycontext.stroke();
mycontext.restore();
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

Colocando texto en lienzo

Supón que deseas incluir texto directamente en tu dibujo de lienzo.

La API canvas proporciona dos comandos para representar texto en el dibujo: fill Text (...) y strokeText (...). Ambos comandos toman los mismos parámetros: (stringTo- Render, x, y, [opcional: maxWidth]). La única diferencia es si el texto se completa o simplemente se resume.

Para establecer el estilo de fuente (tamaño de fuente, tamaño, etc.), usa la propiedad font:

mycontext.font = "25pt Arial";

Ahora, simplemente llama al comando de texto:

mycontext.fillText("Hola mundo", 0, 25);
mycontext.strokeText("Hola mundo", 0, 75);

Ejemplo completo:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<!--<link rel="stylesheet" type="text/css" href="styles/application.css">-->
<script src="js/prefixfree.js"></script>
</head>
<body>
<script>
// My context
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
// cambiamos las dimensiones
mycanvas.width = 200;
mycanvas.height = 200;
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
// Texto
mycontext.font = "25pt Arial";
mycontext.fillText("Hola mundo", 0, 25);
mycontext.strokeText("Hola mundo", 0, 75);
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

Dibujos de lienzo de recorte

Supón que deseas utilizar un comando de dibujo (como texto), pero quieres recortar el dibujo mediante alguna otra forma que definas.

La API de canvas proporciona el comando clip(...), que tomará la ruta actualmente definida y la usará como máscara de recorte para los siguientes comandos de dibujo. Esto significa que el elemento canvas sólo dibujará dentro de los límites de máscara de recorte definidos y descartará cualquier dibujo fuera de la ruta.

Para agregar el texto de la letra "H", pero con un círculo, debes hacer lo siguiente:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<!--<link rel="stylesheet" type="text/css" href="styles/application.css">-->
<script src="js/prefixfree.js"></script>
</head>
<body>
<script>
// My context
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
// cambiamos las dimensiones
mycanvas.width = 200;
mycanvas.height = 200;
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
// Texto
mycontext.beginPath();
mycontext.arc(50, 50, 25, 0, Math.PI * 2, true);
mycontext.clip(); //
mycontext.fillStyle = "#f00";
mycontext.font = "50pt Arial";
mycontext.fillText("H", 25, 75);
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

Animar dibujos de canvas

Dibujar formas estáticas en el elemento canvas está bien, pero ahora quieres hacer que las formas se mueven alrededor.

La animación con el elemento de canvas se reduce a dibujar un cuadro de tu animación, luego algunos milisegundos más tarde, borrando ese dibujo y volviendo a dibujar el siguiente cuadro, probablemente con algunos elementos ligeramente movidos o modificados. Si animas mostrando los cuadros lo suficientemente rápido, alrededor de 20-30 fotogramas por segundo, generalmente se ve como una animación suave de tus formas.

En este tema ya se ha explicado cómo dibujar varias cosas en su elemento canvas.

También se ha mencionado brevemente una forma de borrar su elemento canvas (restablecer el ancho). Para activar algunas animaciones, hay que unir esos dos conceptos.

Aquí hay un ejemplo básico de un punto rojo en movimiento:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> Canvas </title>
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/3.7.3/build/cssreset/cssreset-min.css" data-noprefix>
<!--<link rel="stylesheet" type="text/css" href="styles/application.css">-->
<script src="js/prefixfree.js"></script>
</head>
<body>
<script>
// My context
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
// cambiamos las dimensiones
mycanvas.width = 800;
mycanvas.height = 800;
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
// Punto moviendose
function draw_circle(x, y) {
mycontext.fillStyle = "#f00";
mycontext.beginPath();
mycontext.arc(x, y, 10, 0, Math.PI * 2, true);
mycontext.fill();
}
function erase_frame() {
mycanvas.width = mycanvas.width;
}
var ball_x = 50;
var ball_y = 50;
var delta = 3;
draw_circle(ball_x, ball_y);
setInterval(function(){
if (ball_x > 100 || ball_y < 15 || ball_x < 15 || ball_y > 100) {
delta = delta*(-1);
}
ball_x += delta;
ball_y += delta;
erase_frame();
draw_circle(ball_x, ball_y);
}, 35);
</script>
</body>
</html>

Haz clic aquí para observar el resultado.

 

Dibujando gráficos con canvas

Supón que tienes algunos datos que deseas trazar en un gráfico utilizando un elemento canvas.

Todos los comandos API de canvas discutidos en este capítulo, más otros comandos avanzados (para curvas complejas, etc.), pueden combinarse para crear gráficos de aspecto agradable que visualicen datos, ya sea de línea, pastel u otros tipos de gráficos.

Como probablemente puedes imaginar, la complejidad de tal tarea es bastante alta. Por lo tanto, se usará una biblioteca gráfica simple y gratuita llamada flot.

La biblioteca flot usa jQuery, por lo que primero debes cargar una versión reciente de jQuery y luego la última versión de la biblioteca flot:

<script src="jquery.js"></script>
<script src="jquery.flot.js"></script>

A continuación debes crear un elemento de marcador de posición en tu página, en el que flotará el gráfico de canvas. La biblioteca flotará automáticamente las dimensiones renderizadas del mapa de bits del elemento canvas con el tamaño del elemento marcador de posición que especifique:

<div id = "my_graph" style = "width: 600px; height: 300px"> </ div>

Ahora necesitas configurar los datos que trazarás en tu gráfico. Puedes cargar estos datos dinámicamente utilizando Ajax, o puedes incluir los datos en línea en el código del script, como se muestra aquí:

var graph_data = [[0, 3], [4, 8], [8, 5], [9, 13]]; 

El formato de los datos es una matriz de pares [X, Y] para cada punto de datos, que representa valores para los ejes X e Y para cada punto, respectivamente.

Una vez que tengas los datos del gráfico, si las opciones gráficas predeterminadas son aceptables, simplemente llama directamente a la API de gráficos flot, pasando sus datos:

var my_graph = $ ("# my_graph"); // obtener una referencia al marcador de posición
$ .plot (my_graph, [graph_data]); // pasa los datos del gráfico como una serie de datos

Notarás que pasamos los datos del gráfico dentro de [], lo que significa que pasamos una matriz alrededor de nuestros datos del gráfico. La API de gráficos flot es compatible con la representación gráfica de múltiples series de datos a la vez en un gráfico. En nuestro ejemplo, nuestros datos de gráficos fueron sólo una de esas series de datos, pero podría haber pasado otras series de datos como se desee. Las opciones y los estilos predeterminados darán como resultado un bonito gráfico, como se muestra en:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<title> Canvas </title>
<script type="text/javascript" src="Scripts/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="Scripts/flot/jquery.flot.js"></script>
</head>
<body>
<div id="my_graph" style="width:600px; height:300px"></div>
<script>
// My context
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
// cambiamos las dimensiones
mycanvas.width = 800;
mycanvas.height = 800;
document.body.appendChild(mycanvas);
var mycanvas = document.getElementById("mycanvas");
var mycontext = mycanvas.getContext("2d");
var graph_data = [[0, 3], [4, 8], [8, 5], [9, 13]];
var my_graph = $("#my_graph"); // get a reference to the placeholder
$.plot(my_graph, [graph_data]); // pass the graph data as one data-series
</script>
</body>
</html>

Haz clic aquí para observar el resultado.


Puedes ver que, con sólo unas pocas líneas de código, se puede aprovechar el poder de la biblioteca flot para generar un gráfico de aspecto profesional, en lugar de tener que escribir cientos de líneas de tu propio código API de canvas.

La biblioteca flot API te permite generar y mostrar etiquetas manualmente para los ejes X e Y, controlar el rango mínimo y máximo para cada eje, definir manualmente el tamaño de paso de la cuadrícula para cada eje, controlar colores y estilos de línea, y mucho más.

 

Guardar un dibujo de canvas en un archivo

Supón que deseas guardar el dibujo actual en un elemento canvas en un archivo.

El API canvas proporciona el comando toDataURL (...), que extraerá los datos de imagen del elemento canvas en el formato de imagen especificado.

var canvas = $("canvas", my_graph)[0];
var image_data = canvas.toDataURL("image/png");

Ahora que tienes los datos de imagen en bruto, puedes guardar los datos de la imagen como lo desees.

Por ejemplo, para enviar los datos de imagen a un servidor a través de Ajax, utilizando jQuery, puedes usar:

$.post("http://location/path/to/upload", {data: image_data});

A continuación se presenta un ejemplo completo donde verás dos imágenes de una nube, la primera es una imagen canvas, la segunda imagen puede ser bajada al dar clic en ella y seleccionar “guardar imagen como”:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<title> Canvas </title>
<script type="text/javascript" src="Scripts/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="Scripts/flot/jquery.flot.js"></script>
</head>
<body>
<script>
window.onload = function(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
// draw cloud
context.beginPath(); // Empezamos la nube
context.moveTo(170, 80);
context.bezierCurveTo(130, 100, 130, 150, 230, 150);
context.bezierCurveTo(250, 180, 320, 180, 340, 150);
context.bezierCurveTo(420, 150, 420, 120, 390, 100);
context.bezierCurveTo(430, 40, 370, 30, 340, 50);
context.bezierCurveTo(320, 5, 250, 20, 250, 50);
context.bezierCurveTo(200, 5, 150, 20, 170, 80);
context.closePath(); // teminamos la nube
context.lineWidth = 5;
context.fillStyle = "#8ED6FF";
context.fill();
context.strokeStyle = "#0000ff";
context.stroke();
// Salvamos la imagen canvas como dato url (usando png como formato por defecto)
var dataURL = canvas.toDataURL();
// Asignamos la fuente de imagen canvasImg a el dataURL
// de tal forma que pueda ser salvada como imagen
document.getElementById("canvasImg").src = dataURL;
};
</script>
<canvas id="myCanvas" width="578" height="200"></canvas>
<p>
Imagen:
</p>
<img id="canvasImg" alt="Right click to save me!">
</body>
</html>

Haz clic aquí para observar el resultado.

Cierre


Con este tema se termina el ciclo de cómo desarrollar gráficos utilizando tecnología HTML5, CSS3 y JavaScript. Aunado al uso de SVG se puede cubrir una amplia gama de formas de hacer gráficas de diferentes tipos y en diferentes combinaciones. Cabe aclarar que son temas muy amplios y que incluso hay tomos y cursos completos de cada tecnología.

Trata de incorporar a tus proyectos ambas tecnologías para que el producto final sea de la mejor calidad.

Checkpoint


Asegúrate de:

  • Desarrollar gráficos usando el elemento canvas de HTML5.
  • Incluir en tus gráficos transparencias, dimensiones, gradientes, imágenes, texto, etcétera.
  • Desarrollar gráficos de negocios de líneas usando canvas.

Referencias


  • Schmitt, C. (2012). HTML5 Cookbook. EE. UU.: O’Reilly Media.
  • Rowell, E. (2011). HTML5 Canvas Cookbook. Reino Unido: Packt Publishing Ltd.