El elemento <canvas> de HTML es una poderosa herramienta para el renderizado dinámico de gráficos en dos dimensiones directamente en el navegador web, utilizando JavaScript. Actúa como un lienzo en blanco o un mapa de bits donde los desarrolladores pueden dibujar una amplia variedad de elementos visuales, desde formas geométricas simples hasta imágenes y texto complejo.
Es importante destacar que el elemento <canvas> por sí mismo es solo un contenedor. La magia ocurre cuando se interactúa con su interfaz de programación (API) a través de JavaScript, que proporciona un conjunto rico de métodos para controlar cada píxel y propiedad visual.
Primeros Pasos con Canvas
Para empezar a dibujar, es necesario obtener una referencia al elemento <canvas> en el Document Object Model (DOM) y luego acceder a su contexto de dibujo. Para gráficos 2D, se utiliza el método getContext("2d"), el cual devuelve un objeto que encapsula todas las funcionalidades de dibujo.
El sistema de coordenadas de Canvas se basa en una cuadrícula bidimensional donde el punto (0,0) se sitúa en la esquina superior izquierda del lienzo. Las coordenadas X aumentan hacia la derecha y las coordenadas Y aumentan hacia abajo.
Dibujando Rectángulos
Los rectángulos son una de las formas más básicas y se pueden dibujar tanto rellenos como contorneados. Los métodos fillRect(x, y, ancho, alto) y strokeRect(x, y, ancho, alto) permiten definir la posición y las dimensiones de un rectángulo, mientras que propiedades como fillStyle y strokeStyle controlan el color de relleno y del borde, respectivamente.
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas - Rectángulos</title>
<style>
canvas {
border: 1px solid #ddd;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<h2>Ejemplo de Rectángulos en HTML Canvas</h2>
<canvas id="lienzoRectangulos" width="400" height="200">
Tu navegador no soporta el elemento Canvas.
</canvas>
<script>
const lienzoRect = document.getElementById("lienzoRectangulos");
const ctx = lienzoRect.getContext("2d");
// Rectángulo azul claro relleno
ctx.fillStyle = "#ADD8E6"; // Light Blue
ctx.fillRect(30, 30, 150, 100);
// Rectángulo verde contorneado
ctx.strokeStyle = "#2E8B57"; // Sea Green
ctx.lineWidth = 4;
ctx.strokeRect(200, 50, 120, 80);
// Rectángulo rojo relleno, con transparencia
ctx.fillStyle = "rgba(255, 99, 71, 0.7)"; // Tomato con 70% de opacidad
ctx.fillRect(70, 80, 100, 100);
</script>
</body>
</html>
Dibujando Líneas
Para trazar líneas, se utilizan una serie de comandos de ruta. El método beginPath() inicia una nueva ruta de dibujo. Luego, moveTo(x, y) establece el punto de inicio de la línea, y lineTo(x, y) añade un nuevo punto al que se conectará la línea. Finalmente, stroke() aplica el trazo de la línea con el estilo definido por strokeStyle y lineWidth.
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas - Líneas</title>
<style>
canvas {
border: 1px solid #ddd;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<h2>Ejemplo de Dibujo de Líneas en Canvas</h2>
<canvas id="lienzoLineas" width="400" height="200">
Tu navegador no soporta el elemento Canvas.
</canvas>
<script>
const lienzoLineas = document.getElementById("lienzoLineas");
const ctx = lienzoLineas.getContext("2d");
// Línea diagonal roja
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(350, 150);
ctx.strokeStyle = "red";
ctx.lineWidth = 3;
ctx.stroke();
// Línea discontinua azul
ctx.beginPath();
ctx.moveTo(50, 150);
ctx.lineTo(350, 50);
ctx.strokeStyle = "blue";
ctx.lineWidth = 2;
ctx.setLineDash([5, 5]); // Patrón de guiones y espacios
ctx.stroke();
ctx.setLineDash([]); // Restaurar a línea sólida para futuros dibujos
</script>
</body>
</html>
Dibujando Círculos y Arcos
Los círculos y arcos se crean utilizando el método arc(x, y, radio, anguloInicio, anguloFin, sentidoAntihorario). Los ángulos se especifican en radianes (donde 0 es a las 3 en punto y 2 * Math.PI completa un círculo). El último parámetro opcional, sentidoAntihorario, define la dirección del arco.
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas - Círculos</title>
<style>
canvas {
border: 1px solid #ddd;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<h2>Ejemplo de Círculos y Arcos en Canvas</h2>
<canvas id="lienzoCirculos" width="400" height="200">
Tu navegador no soporta el elemento Canvas.
</canvas>
<script>
const lienzoCirc = document.getElementById("lienzoCirculos");
const ctx = lienzoCirc.getContext("2d");
// Círculo relleno de color púrpura
ctx.beginPath();
ctx.arc(100, 100, 70, 0, 2 * Math.PI); // Centro (100,100), radio 70
ctx.fillStyle = "#8A2BE2"; // Blue Violet
ctx.fill();
// Arco contorneado amarillo (medio círculo)
ctx.beginPath();
ctx.arc(300, 100, 50, 0, Math.PI, false); // Medio círculo en sentido horario
ctx.strokeStyle = "#FFD700"; // Gold
ctx.lineWidth = 5;
ctx.stroke();
// Pequeño círculo contorneado dentro del primero
ctx.beginPath();
ctx.arc(100, 100, 20, 0, 2 * Math.PI);
ctx.strokeStyle = "white";
ctx.lineWidth = 2;
ctx.stroke();
</script>
</body>
</html>
Renderizando Texto
Canvas ofrece métodos para dibujar texto directamente sobre el lienzo. Se pueden controlar propiedades como la fuente (font), el color (fillStyle o strokeStyle), la alineación horizontal (textAlign) y vertical (textBaseline). Los métodos fillText(texto, x, y) y strokeText(texto, x, y) permiten dibujar texto relleno y contorneado, respectivamente.
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas - Texto</title>
<style>
canvas {
border: 1px solid #ddd;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<h2>Ejemplo de Renderizado de Texto en Canvas</h2>
<canvas id="lienzoTexto" width="500" height="250">
Tu navegador no soporta el elemento Canvas.
</canvas>
<script>
const lienzoText = document.getElementById("lienzoTexto");
const ctx = lienzoText.getContext("2d");
// Texto relleno estándar
ctx.font = "48px serif";
ctx.fillStyle = "#4682B4"; // Steel Blue
ctx.fillText("¡Hola Canvas!", 20, 80);
// Texto contorneado y más grande
ctx.font = "60px Impact";
ctx.strokeStyle = "#DAA520"; // Goldenrod
ctx.lineWidth = 2;
ctx.strokeText("Texto Stroke", 20, 150);
// Texto centrado y con sombra
ctx.font = "italic 30px Arial";
ctx.fillStyle = "#5F9EA0"; // Cadet Blue
ctx.textAlign = "center";
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
ctx.shadowBlur = 5;
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
ctx.fillText("Centrado y Sombreado", lienzoText.width / 2, 220);
</script>
</body>
</html>
Aplicando Gradientes
Los gradientes permiten un relleno con transiciones suaves entre múltiples colores, añadiendo profundidad y dinamismo a los gráficos. Canvas soporta dos tipos principales de gradientes: lineales y radiales.
Gradientes Lineales
Se crean con createLinearGradient(x0, y0, x1, y1), donde (x0, y0) y (x1, y1) definen la línea a lo largo de la cual el gradiente progresa. Después, se añaden puntos de color (addColorStop(posición, color)) para especificar los colores en diferetnes porcentajes de la línea del gradiente (0 a 1).
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas - Gradiente Lineal</title>
<style>
canvas {
border: 1px solid #ddd;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<h2>Ejemplo de Gradiente Lineal en Canvas</h2>
<canvas id="lienzoGradienteLinear" width="400" height="200">
Tu navegador no soporta el elemento Canvas.
</canvas>
<script>
const lienzoGL = document.getElementById("lienzoGradienteLinear");
const ctx = lienzoGL.getContext("2d");
// Crear un gradiente lineal de izquierda a derecha
const gradienteHorizontal = ctx.createLinearGradient(0, 0, 400, 0);
gradienteHorizontal.addColorStop(0, "darkred");
gradienteHorizontal.addColorStop(0.5, "orange");
gradienteHorizontal.addColorStop(1, "yellow");
ctx.fillStyle = gradienteHorizontal;
ctx.fillRect(0, 0, 400, 200);
// Texto con gradiente
ctx.font = "bold 50px sans-serif";
ctx.strokeStyle = gradienteHorizontal; // Usar el gradiente para el borde del texto
ctx.lineWidth = 2;
ctx.strokeText("GRADIENTE", 60, 120);
</script>
</body>
</html>
Gradientes Radiales
Los gradientes radiales se definen mediante dos círculos con createRadialGradient(x0, y0, r0, x1, y1, r1). El primer círculo (x0, y0, r0) define el punto de inicio del gradiente, y el segundo (x1, y1, r1) define el punto final. Los colores se añaden de la misma manera que en los gradientes lineales.
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas - Gradiente Radial</title>
<style>
canvas {
border: 1px solid #ddd;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<h2>Ejemplo de Gradiente Radial en Canvas</h2>
<canvas id="lienzoGradienteRadial" width="400" height="200">
Tu navegador no soporta el elemento Canvas.
</canvas>
<script>
const lienzoGR = document.getElementById("lienzoGradienteRadial");
const ctx = lienzoGR.getContext("2d");
// Crear un gradiente radial (del centro hacia afuera)
const gradienteRadial = ctx.createRadialGradient(200, 100, 10, 200, 100, 150); // Centro (200,100), radio interno 10, radio externo 150
gradienteRadial.addColorStop(0, "white"); // Blanco en el centro
gradienteRadial.addColorStop(0.5, "deepskyblue"); // Azul cielo en la mitad
gradienteRadial.addColorStop(1, "navy"); // Azul marino en el borde
ctx.fillStyle = gradienteRadial;
ctx.fillRect(0, 0, 400, 200);
</script>
</body>
</html>
Dibujando Imágenes
El método drawImage() permite renderizar imágenes de varios orígenes (elementos <img>, otros elementos <canvas>, <video>, etc.) en el lienzo. Ofrece varias sobrecargas para controlar la posición, el tamaño y el recorte de la imagen.
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas - Imágenes</title>
<style>
canvas {
border: 1px solid #ddd;
display: block;
margin: 20px auto;
}
#imagenOriginal {
display: none; /* Ocultar la imagen original */
}
</style>
</head>
<body>
<h2>Ejemplo de Dibujo de Imágenes en Canvas</h2>
<!-- Imagen de ejemplo (reemplaza 'placeholder.png' con una URL real) -->
<img id="imagenOriginal" src="https://picsum.photos/id/237/200/150" alt="Imagen de un cachorro" width="200" height="150">
<canvas id="lienzoImagen" width="400" height="250">
Tu navegador no soporta el elemento Canvas.
</canvas>
<script>
window.onload = function() {
const lienzoImg = document.getElementById("lienzoImagen");
const ctx = lienzoImg.getContext("2d");
const miImagen = document.getElementById("imagenOriginal");
// Asegurarse de que la imagen esté completamente cargada
miImagen.onload = function() {
// Dibujar la imagen en su tamaño original en la posición (50, 50)
ctx.drawImage(miImagen, 50, 50);
// Dibujar la imagen escalada a un nuevo tamaño en la posición (250, 20)
ctx.drawImage(miImagen, 250, 20, 100, 75); // X, Y, Ancho, Alto
// Dibujar un fragmento de la imagen (recorte)
// drawImage(imagen, sx, sy, sAncho, sAlto, dx, dy, dAncho, dAlto)
// sx, sy, sAncho, sAlto: fragmento de la imagen fuente
// dx, dy, dAncho, dAlto: posición y tamaño en el lienzo de destino
ctx.drawImage(miImagen, 0, 0, 100, 75, 250, 100, 150, 112.5); // Recortar la esquina superior izquierda y escalar
ctx.font = "18px sans-serif";
ctx.fillStyle = "black";
ctx.fillText("Imágenes en Canvas", 120, 30);
};
// En caso de que la imagen ya se hubiera cargado antes del 'onload'
if (miImagen.complete) {
miImagen.onload();
}
};
</script>
</body>
</html>