HTML5 · Capítulo 11

API Canvas

Dibujando en la Web

El lienzo que reemplazó a Flash: gráficos 2D, animaciones, video y mucho más.

✏️ Dibuja con el mouse o el dedo · Doble clic para borrar
◀ ▶ Navega con flechas ● Barra de progreso 👆 Swipe en móvil

El lienzo y el contexto

Elemento <canvas> crea un área de dibujo. Atributos: width y height.

<canvas id="canvas" width="500" height="300"></canvas>

Contexto Se obtiene con getContext('2d') o 'webgl' (3D).

const canvas = document.getElementById('canvas');
                    const ctx = canvas.getContext('2d');
📐 Origen (0,0) — esquina superior izquierda. Los ejes X e Y aumentan hacia la derecha y hacia abajo.

WebGL se estudia en el próximo capítulo. Todos los navegadores modernos soportan 2d.

Rectángulos y colores

Métodos directos

  • fillRect(x, y, w, h) — relleno
  • strokeRect(x, y, w, h) — contorno
  • clearRect(x, y, w, h) — borrador
ctx.strokeRect(100,100,120,120);
                            ctx.fillRect(110,110,100,100);
                            ctx.clearRect(120,120,80,80);

Colores

  • fillStyle — relleno
  • strokeStyle — línea
  • globalAlpha — transparencia (0.0–1.0)
ctx.fillStyle = '#000099';
                            ctx.strokeStyle = 'rgba(255,0,0,0.7)';

Los colores usan sintaxis CSS: hexadecimales, rgb(), rgba().

Gradientes: createLinearGradient(), createRadialGradient() y addColorStop().

Trazados

Un trazado es un "mapa" que el lápiz sigue. Se inicia con beginPath() y se dibuja con stroke(), fill() o clip().

Comandos

  • moveTo(x, y)
  • lineTo(x, y)
  • rect(x, y, w, h)
  • arc(x, y, r, a1, a2, dir)
  • quadraticCurveTo(cpx, cpy, x, y)
  • bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

Ejemplo

ctx.beginPath();
                            ctx.moveTo(100,100);
                            ctx.lineTo(200,200);
                            ctx.lineTo(100,200);
                            ctx.closePath(); // opcional
                            ctx.stroke();    // o .fill()

fill() cierra automáticamente el trazado. clip() crea una máscara de recorte.

Líneas, texto y sombras

Líneas

  • lineWidth — grosor
  • lineCap — extremos: butt, round, square
  • lineJoin — uniones: round, bevel, miter
  • miterLimit — límite del pico

Texto

  • font — igual que CSS
  • textAlign / textBaseline
  • fillText(text, x, y)
  • strokeText(text, x, y)
  • measureText(text) — devuelve width

Sombras

  • shadowColor, shadowOffsetX, shadowOffsetY, shadowBlur
ctx.shadowColor = 'rgba(0,0,0,0.5)';
                    ctx.shadowOffsetX = 4; ctx.shadowOffsetY = 4;
                    ctx.shadowBlur = 5;
                    ctx.font = 'bold 50px verdana';
                    ctx.fillText('Mi Mensaje', 100, 100);

Transformaciones y estado

Métodos

  • translate(x, y) — mover origen
  • rotate(ángulo) — radianes
  • scale(x, y) — escalar (negativos = espejo)
  • transform(m1,m2,m3,m4,dx,dy) — matriz
  • setTransform(...) — reinicia y aplica

Guardar / Restaurar

  • save() — guarda el estado actual
  • restore() — recupera el último guardado

Acumulativas: cada transformación se suma a la anterior.

ctx.save();
                    ctx.translate(50,70);
                    ctx.rotate(Math.PI/4);
                    ctx.fillText('Rotado', 0, 0);
                    ctx.restore();

globalCompositeOperation 12 modos de combinación (source-over, xor, destination-in, etc.)

Imágenes

drawImage(imagen, x, y) — 3 versiones: simple, con escalado, y con recorte.

  • Fuente: <img>, <video> o <canvas>
  • Usar evento load para asegurar descarga
const img = document.createElement('img');
                    img.src = 'foto.jpg';
                    img.onload = () => ctx.drawImage(img, 20, 20);

Patrones

createPattern(imagen, tipo)repeat, repeat-x, repeat-y, no-repeat

Datos de imagen

  • getImageData(x, y, w, h) → objeto con data (RGBA)
  • putImageData(imagenData, x, y)

Acceso por píxeles: data[(w*4*y) + (x*4) + n]

⚠️ Origen cruzado: usar crossOrigin="anonymous" y cabeceras CORS.

Animaciones

No hay un método mágico: se borra el lienzo y se redibuja en cada fotograma.

Bucle profesional

requestAnimationFrame(fn) — sincronizado con el refresco del navegador.
function bucle() {
                            ctx.clearRect(0,0,500,300);
                            dibujar();
                            requestAnimationFrame(bucle);
                            }

Ejemplo: ojos que siguen al ratón

  • Evento mousemove
  • Math.atan2() para el ángulo
  • Math.sin() y Math.cos() para posición del iris

También se puede usar setInterval() pero es menos fluido.

Videojuego simple: nave que se mueve hacia donde se hace clic, con velocidad creciente. Colisión con bordes → Game Over.

Video en Canvas

drawImage(video, x, y) dibuja el fotograma actual del <video>.

const video = document.getElementById('medio');
                    setInterval(() => {
                    ctx.drawImage(video, 0, 0);
                    }, 33); // ~30 fps
Efecto espejo: ctx.translate(ancho, 0); ctx.scale(-1, 1);

Aplicación real: instantánea con cámara

  • navigator.mediaDevices.getUserMedia({video: true})
  • Reproducir en <video> y capturar fotogramas en <canvas>
  • Convertir a imagen con toDataURL() o toBlob()

© Video: Big Buck Bunny (Blender Foundation)

Extraer datos y más

toDataURL() y toBlob()

  • canvas.toDataURL('image/png') → cadena data:url
  • canvas.toBlob(callback, 'image/jpeg') → objeto Blob

Útil para guardar, compartir o subir al servidor.

¡El lienzo es el límite! 🚀

📖 Capítulo 11 · API Canvas 🔗 Más info en developer.mozilla.org
1 / 10