Capítulo 1: Fundamentos de Canvas
Canvas es una API de HTML5 que permite dibujar gráficos mediante scripts (generalmente JavaScript). Proporciona un área de dibujo en la página web donde puedes crear gráficos, animaciones, juegos y visualizaciones de datos.
Configuración básica
<!DOCTYPE html> <html> <head> <title>Canvas Básico</title> </head> <body> <canvas id="miCanvas" width="800" height="600"> Tu navegador no soporta el elemento canvas. </canvas> <script> // Obtener el elemento canvas const canvas = document.getElementById('miCanvas'); const ctx = canvas.getContext('2d'); // Tu código de dibujo irá aquí </script> </body> </html>
El contexto de dibujo
- 2d: Contexto para gráficos 2D
- webgl: Contexto para gráficos 3D (más avanzado)
Capítulo 2: Formas y Trazados Básicos
Rectángulos
// Rectángulo relleno ctx.fillStyle = 'blue'; ctx.fillRect(10, 10, 100, 50); // Rectángulo con borde ctx.strokeStyle = 'red'; ctx.lineWidth = 3; ctx.strokeRect(120, 10, 100, 50); // Limpiar área rectangular ctx.clearRect(15, 15, 90, 40);
Líneas y trazados
// Iniciar un nuevo trazado ctx.beginPath(); ctx.moveTo(50, 50); // Punto inicial ctx.lineTo(150, 50); // Línea horizontal ctx.lineTo(100, 150); // Línea diagonal ctx.closePath(); // Cerrar el trazado ctx.stroke(); // Dibujar el contorno
Formas básicas
// Círculo/arco ctx.beginPath(); ctx.arc(200, 200, 50, 0, Math.PI * 2); // (x, y, radio, inicio, fin) ctx.fillStyle = 'green'; ctx.fill(); // Triángulo ctx.beginPath(); ctx.moveTo(300, 300); ctx.lineTo(350, 250); ctx.lineTo(400, 300); ctx.closePath(); ctx.stroke();
Capítulo 3: Estilos y Colores
Colores y rellenos
// Colores sólidos ctx.fillStyle = 'red'; ctx.fillStyle = '#ff0000'; ctx.fillStyle = 'rgb(255, 0, 0)'; ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; // Con transparencia // Gradientes lineales const gradient = ctx.createLinearGradient(0, 0, 200, 0); gradient.addColorStop(0, 'red'); gradient.addColorStop(1, 'blue'); ctx.fillStyle = gradient; ctx.fillRect(10, 10, 200, 100); // Gradientes radiales const radialGradient = ctx.createRadialGradient(100, 100, 10, 100, 100, 50); radialGradient.addColorStop(0, 'white'); radialGradient.addColorStop(1, 'black'); ctx.fillStyle = radialGradient; ctx.fillRect(50, 50, 100, 100);
Estilos de línea
ctx.lineWidth = 5; // Grosor de línea ctx.lineCap = 'round'; // 'butt', 'round', 'square' ctx.lineJoin = 'bevel'; // 'round', 'bevel', 'miter' ctx.setLineDash([5, 15]); // Línea punteada ctx.lineDashOffset = 0;
Capítulo 4: Texto e Imágenes
Trabajar con texto
// Propiedades de texto ctx.font = '30px Arial'; ctx.fillStyle = 'black'; ctx.textAlign = 'center'; // 'start', 'end', 'left', 'right', 'center' ctx.textBaseline = 'middle'; // 'top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom' // Dibujar texto relleno ctx.fillText('Hola Canvas', 200, 50); // Dibujar texto con contorno ctx.strokeText('Texto con borde', 200, 100); // Medir texto const metrics = ctx.measureText('Texto de ejemplo'); console.log(metrics.width); // Ancho del texto
Trabajar con imágenes
// Dibujar imagen completa const img = new Image(); img.src = 'imagen.jpg'; img.onload = function() { ctx.drawImage(img, 10, 10); // (imagen, x, y) // Escalar imagen ctx.drawImage(img, 10, 150, 100, 50); // (imagen, x, y, ancho, alto) // Recortar y dibujar parte de la imagen ctx.drawImage(img, 50, 50, 100, 100, 150, 150, 100, 100); // (imagen, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) };
Capítulo 5: Transformaciones y Composición
Transformaciones básicas
// Guardar el estado actual ctx.save(); // Traslación ctx.translate(100, 100); ctx.fillRect(0, 0, 50, 50); // Se dibuja en (100, 100) // Rotación ctx.rotate(Math.PI / 4); // 45 grados ctx.fillRect(0, 0, 50, 50); // Escala ctx.scale(2, 2); ctx.fillRect(0, 0, 50, 50); // Se dibuja con el doble de tamaño // Restaurar estado ctx.restore();
Modos de composición
ctx.globalCompositeOperation = 'source-over'; // Valor por defecto // Otros modos: 'source-in', 'source-out', 'source-atop', // 'destination-over', 'destination-in', etc. ctx.globalAlpha = 0.5; // Transparencia global
Capítulo 6: Animación y Optimización
Bucle de animación básico
function animar() { // Limpiar canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Actualizar posición/dibujar // ... // Solicitar siguiente frame requestAnimationFrame(animar); } // Iniciar animación animar();
Ejemplo de animación: Pelota rebotando
let x = 100; let y = 100; let dx = 2; let dy = 2; const radio = 20; function dibujarPelota() { ctx.beginPath(); ctx.arc(x, y, radio, 0, Math.PI * 2); ctx.fillStyle = 'red'; ctx.fill(); ctx.closePath(); } function actualizar() { // Limpiar ctx.clearRect(0, 0, canvas.width, canvas.height); // Dibujar dibujarPelota(); // Actualizar posición x += dx; y += dy; // Rebotar en bordes if (x + radio > canvas.width || x - radio < 0) { dx = -dx; } if (y + radio > canvas.height || y - radio < 0) { dy = -dy; } requestAnimationFrame(actualizar); } actualizar();
Optimizaciones importantes
// 1. Usar requestAnimationFrame en lugar de setInterval // 2. Dibujar solo lo que cambia cuando sea posible // 3. Pre-renderizar elementos complejos // 4. Usar múltiples canvases para capas // 5. Limitar el área de redibujado // Ejemplo: dibujar solo el área que cambia function dibujarEficiente(x, y, ancho, alto) { // En lugar de limpiar todo el canvas ctx.clearRect(x, y, ancho, alto); // Dibujar solo en esa área }
Ejemplos Prácticos
Ejemplo 1: Formas Básicas
Ejemplo 2: Gradientes y Estilos
Ejemplo 3: Texto y Transformaciones
Ejemplo 4: Animación (Pelota Rebotando)
Nota: Estos ejemplos muestran en práctica los conceptos explicados en la guía. Puedes inspeccionar el código fuente para ver cómo se implementan.