CodeForge

Maquetación Web Dinámica / Canvas y videojuegos 2D

El contexto 2D: formas, colores, texto e imágenes

Teoría22 min20 XP

El contexto 2D (ctx) es tu caja de pinceles completa: rectángulos, círculos, líneas, texto, imágenes y degradados. Esta lección es tu referencia práctica — la paleta que tendrás abierta mientras construyes todo lo demás del módulo. No memorices: entiende el patrón y ten esto a mano.

El patrón fundamental: fijar estado, luego dibujar

Rectángulos: los únicos con método directo

rects.js
// relleno: x, y, ancho, alto
ctx.fillStyle = "#6d28d9";
ctx.fillRect(20, 20, 100, 60);

// solo contorno
ctx.strokeStyle = "#22c55e";
ctx.lineWidth = 4;
ctx.strokeRect(20, 20, 100, 60);

// BORRAR una región (deja transparente) — clave para animar
ctx.clearRect(0, 0, canvas.width, canvas.height);

clearRect es especial: limpia píxeles a transparente. Es la primera línea de casi todo game loop ("borra el fotograma anterior antes de pintar el nuevo") — lo verás en la lección 3.

Todo lo demás: el sistema de paths

Círculos, triángulos, líneas y formas libres usan un lápiz imperativo, primo del <path> de SVG pero en pasos de código:

paths.js
ctx.beginPath();                 // "empieza un trazo nuevo"
ctx.arc(160, 75, 40, 0, Math.PI * 2);  // círculo: cx, cy, radio, desde, hasta (radianes)
ctx.fillStyle = "#6d28d9";
ctx.fill();                      // rellénalo

ctx.beginPath();
ctx.moveTo(40, 120);             // lápiz a un punto (sin dibujar)
ctx.lineTo(90, 40);              // línea hasta...
ctx.lineTo(140, 120);            // ...y otra: un triángulo abierto
ctx.closePath();                 // cierra la figura
ctx.stroke();                    // dibújala en contorno

La regla de oro que evita el 90% de los bugs de canvas: beginPath() antes de cada figura nueva. Sin él, la figura nueva se conecta con la anterior (todas comparten el mismo trazo) y salen líneas fantasma cruzando el lienzo. Un beginPath() "levanta el lápiz y empieza limpio".

El arc mide el ángulo en RADIANES: un círculo completo es Math.PI * 2. Media vuelta es Math.PI. No necesitas trigonometría todavía — memoriza que "círculo completo = Math.PI * 2" y listo.

Texto, imágenes y degradados

extras.js
// texto
ctx.fillStyle = "#1e293b";
ctx.font = "700 24px system-ui";
ctx.textAlign = "center";
ctx.fillText("PUNTAJE: 100", canvas.width / 2, 40);

// imagen (una vez cargada): dibujar en x, y con ancho, alto
const img = new Image();
img.onload = () => ctx.drawImage(img, 10, 10, 64, 64);
img.src = "nave.png";

// degradado como fillStyle
const grad = ctx.createLinearGradient(0, 0, 0, 150);
grad.addColorStop(0, "#38bdf8");
grad.addColorStop(1, "#0b1120");
ctx.fillStyle = grad;
ctx.fillRect(0, 0, canvas.width, 150);

Dos trampas frecuentes: drawImage solo funciona DESPUÉS de que la imagen cargó (por eso va dentro de img.onload), y textAlign = "center" alinea respecto a la X que le pasas — perfecto para centrar puntajes con canvas.width / 2.

Todo junto

Con estos métodos ya puedes dibujar cualquier escena estática. El salto a "escena que se MUEVE" es una sola idea más — la próxima lección.

Dibujas tres círculos con arc() y fill(), pero aparecen conectados por líneas rectas que no pediste, como una constelación. ¿Qué falta?

Mini-reto

Dibuja tu avatar minimalista en canvas: un círculo de cara, dos círculos pequeños de ojos, un arc de media vuelta para la sonrisa (usa el ángulo 0 a Math.PI), y tu nombre centrado debajo con fillText. Cada figura con su beginPath(). Es un retrato de píxeles, y el músculo que necesitas para dibujar personajes de juego.

Qué sigue

Todo lo que dibujaste está congelado. La próxima lección le da el latido: el GAME LOOP con requestAnimationFrame — la máquina que borra y repinta 60 veces por segundo y convierte tus dibujos en animación y, pronto, en juego.