Maquetación Web Dinámica / Canvas y videojuegos 2D
El contexto 2D: formas, colores, texto e imágenes
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
// 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:
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 contornoLa 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
// 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
<canvas id="paleta" width="340" height="190"></canvas>body { font-family: system-ui; padding: 16px; background: #f8fafc; }
canvas { border-radius: 12px; border: 1px solid #e2e8f0; }const canvas = document.getElementById("paleta");
const ctx = canvas.getContext("2d");
// fondo con degradado
const cielo = ctx.createLinearGradient(0, 0, 0, 190);
cielo.addColorStop(0, "#1e1b4b");
cielo.addColorStop(1, "#4c1d95");
ctx.fillStyle = cielo;
ctx.fillRect(0, 0, 340, 190);
// luna (círculo)
ctx.beginPath();
ctx.arc(280, 50, 26, 0, Math.PI * 2);
ctx.fillStyle = "#fde68a";
ctx.fill();
// montañas (triángulos con paths)
ctx.fillStyle = "#0b1120";
ctx.beginPath();
ctx.moveTo(0, 190); ctx.lineTo(90, 90); ctx.lineTo(180, 190);
ctx.closePath(); ctx.fill();
ctx.beginPath();
ctx.moveTo(120, 190); ctx.lineTo(230, 70); ctx.lineTo(340, 190);
ctx.closePath(); ctx.fill();
// texto centrado
ctx.fillStyle = "#f1f5f9";
ctx.font = "700 20px system-ui";
ctx.textAlign = "center";
ctx.fillText("CodeForge", 170, 30);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.