W3docs

API Canvas de JavaScript

Aprende a dibujar gráficos con el elemento canvas de HTML y JavaScript: obtén un contexto 2D, dibuja formas y líneas, aplica transformaciones y anima con requestAnimationFrame.

Introducción a HTML Canvas con JavaScript

El elemento HTML <canvas> es una superficie de dibujo que controlas con JavaScript. A diferencia de las imágenes o SVG, canvas funciona en modo inmediato: no hay objetos de forma que rastrear. Emites comandos de dibujo y los píxeles se pintan de inmediato. Una vez pintada, una forma es simplemente píxeles coloreados — el canvas no tiene memoria de ella, razón por la cual el redibujado es la idea central detrás de cada animación.

Este capítulo recorre cómo obtener un contexto 2D, dibujar formas y líneas, transformar el sistema de coordenadas y animar con requestAnimationFrame.

Esta página cubre el contexto de renderizado 2D (getContext('2d')). Canvas también expone un contexto webgl para gráficos 3D acelerados por hardware, que es una API separada.

Comprender el elemento 'canvas'

El elemento <canvas> crea una superficie de dibujo de tamaño fijo que renderiza gráficos al vuelo. Destaca en trabajos con gráficos intensivos — juegos, gráficas, manipulación de imágenes, efectos de partículas — donde necesitas control a nivel de píxel y altas tasas de fotogramas. Por sí solo, la etiqueta no dibuja nada; es un contenedor vacío y JavaScript hace todo el pintado.

Un detalle importante que conviene aprender pronto: los atributos width y height establecen el tamaño del búfer de dibujo, mientras que width/height de CSS establecen el tamaño mostrado. Si no coinciden, el canvas se estira y los dibujos se ven borrosos o distorsionados. Establece el tamaño con los atributos (o en JS mediante canvas.width/canvas.height), no con CSS, a menos que quieras escalar.

Configuración básica del Canvas

Para empezar a dibujar, coloca una etiqueta <canvas> en tu HTML y luego obtén su contexto de dibujo 2D en JavaScript con getContext('2d'). El objeto de contexto es donde viven todos los métodos de dibujo.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas Example</title>
<style>
  canvas {
    border: 1px solid #000;
  }
</style>
</head>
<body>
<canvas id="myCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('myCanvas');
  const ctx = canvas.getContext('2d');
</script>
</body>
</html>

Aquí definimos un canvas de 200×200, le damos un borde para que puedas ver sus límites y obtenemos el contexto con getContext('2d'). El borde es puramente visual; la superficie del canvas en sí comienza completamente transparente.

Nota el sistema de coordenadas: el origen (0, 0) está en la esquina superior izquierda. El eje x crece hacia la derecha y el eje y crece hacia abajo, por lo que (0, 0) es el borde superior y los valores de y mayores se mueven hacia la parte inferior. Esto confunde a los principiantes que esperan ejes al estilo matemático.

Dibujar formas

La manera más rápida de colocar algo en pantalla es fillRect(x, y, width, height), que dibuja un rectángulo relleno en una sola llamada. Establece fillStyle primero para elegir el color (funciona cualquier cadena de color CSS). También existe strokeRect para un rectángulo solo de contorno y clearRect para borrar una región volviéndola transparente.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rectangle Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="rectangleCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('rectangleCanvas');
  const ctx = canvas.getContext('2d');
  ctx.fillStyle = '#FF0000'; // Set the fill color to red
  ctx.fillRect(20, 20, 150, 100); // Draw the rectangle
</script>
</body>
</html>

Crear líneas y trazados

Las líneas, curvas y formas personalizadas se construyen a partir de trazados. El patrón es siempre el mismo:

  1. beginPath() — inicia un trazado nuevo (si lo omites, la nueva línea se une a la anterior).
  2. moveTo(x, y) — levanta el lápiz y lo coloca sin dibujar.
  3. lineTo(x, y) — dibuja un segmento de línea hacia un nuevo punto (llámalo repetidamente para encadenar segmentos).
  4. stroke() para dibujar el contorno, o fill() para rellenar el área cerrada.

Controla el aspecto de la línea con lineWidth, strokeStyle y lineCap antes de llamar a stroke().

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Line Drawing Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="lineCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('lineCanvas');
  const ctx = canvas.getContext('2d');
  ctx.beginPath(); // Start the path
  ctx.moveTo(50, 50); // Move the pen to (50, 50)
  ctx.lineTo(150, 50); // Draw a line to (150, 50)
  ctx.lineTo(150, 150); // Continue to (150, 150)
  ctx.lineWidth = 4; // Thicker line
  ctx.strokeStyle = 'navy'; // Line color
  ctx.stroke(); // Render the path visible
</script>
</body>
</html>

Dibujar círculos y arcos

Los círculos se dibujan con arc(x, y, radius, startAngle, endAngle), donde los ángulos están en radianes (un círculo completo es 2 * Math.PI). Envuélvelo en un trazado y luego llama a fill() o stroke():

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Circle Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="circleCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('circleCanvas');
  const ctx = canvas.getContext('2d');
  ctx.beginPath();
  // Center (100, 100), radius 60, full circle
  ctx.arc(100, 100, 60, 0, 2 * Math.PI);
  ctx.fillStyle = 'orange';
  ctx.fill();
  ctx.stroke(); // Add an outline on top of the fill
</script>
</body>
</html>

Operaciones avanzadas con Canvas

Transformaciones en Canvas

translate, rotate y scale modifican el sistema de coordenadas del canvas en lugar de las formas individuales. Es fundamental entender que son acumulativas — cada una se construye sobre la anterior, y una rotación gira alrededor del origen actual, no del centro de la forma. Para rotar alrededor de un punto, primero usa translate hacia ese punto y luego aplica rotate.

Dado que las transformaciones se acumulan, envuélvelas en ctx.save() / ctx.restore() para poder volver al estado anterior en lugar de deshacer manualmente cada transformación:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Transformation Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="transformCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('transformCanvas');
  const ctx = canvas.getContext('2d');
  ctx.save(); // Remember the untransformed state
  ctx.translate(50, 50); // Move the canvas origin to (50, 50)
  ctx.rotate((Math.PI / 180) * 25); // Rotate 25 degrees (converted to radians)
  ctx.fillStyle = 'blue'; // Set fill color to blue
  ctx.fillRect(0, 0, 100, 50); // Draw at the new, rotated origin
  ctx.restore(); // Back to the original coordinate system
</script>
</body>
</html>

Animaciones con Canvas

Canvas no tiene animación integrada; creas movimiento borrando y redibujando toda la superficie de forma repetida. El requestAnimationFrame del navegador programa tu función de dibujo para que se ejecute antes del siguiente repintado — típicamente 60 veces por segundo — y se pausa automáticamente cuando la pestaña está oculta, razón por la cual se prefiere sobre setInterval.

El bucle siempre sigue tres pasos: limpiar el canvas (clearRect), actualizar el estado (aquí, la posición x) y luego dibujar el nuevo fotograma. Si olvidas el clearRect, verás una mancha de todos los fotogramas anteriores en lugar de una forma en movimiento.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Animation Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="animationCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('animationCanvas');
  const ctx = canvas.getContext('2d');
  let x = 0; // Starting position
  function drawFrame() {
    ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas for the new frame
    ctx.fillStyle = 'green'; // Set the fill color to green
    ctx.fillRect(x, 20, 50, 50); // Draw a moving rectangle
    x++; // Increment the horizontal position
    if (x > canvas.width) {
      x = 0;
    }
    requestAnimationFrame(drawFrame); // Continue the animation
  }
  drawFrame();
</script>
</body>
</html>

Errores comunes

  • Salida borrosa: tamaño del búfer y tamaño CSS no coinciden. Establece las dimensiones con los atributos width/height, no con CSS, a menos que estés escalando intencionalmente.
  • Formas unidas entre sí: olvidar beginPath() antes de un nuevo trazado hace que continúe el anterior.
  • Las líneas desaparecen: llamaste a stroke() o fill() pero nunca construiste un trazado, o dibujaste fuera de los límites del canvas.
  • La animación deja rastros: falta clearRect al inicio de cada fotograma.
  • No se renderiza nada: el script se ejecutó antes de que existiera el <canvas> en el DOM. Coloca el script después del elemento o ejecútalo en DOMContentLoaded.

Conclusión

El elemento <canvas> te ofrece una superficie de baja abstracción y píxel perfecto para gráficos que HTML y CSS no pueden producir: gráficas, edición de imágenes, sistemas de partículas y juegos completos. La API es pequeña — obtén un contexto, establece un estilo, emite un comando de dibujo — y las animaciones son simplemente ese bucle ejecutado muchas veces por segundo.

Para profundizar, consulta la etiqueta canvas de HTML y conceptos básicos de dibujo en canvas para la parte del marcado, y animaciones con JavaScript y la API de animaciones basada en requestAnimationFrame para movimiento más fluido. Para seleccionar tu canvas de forma fiable, revisa getElement y querySelector.

Práctica

Práctica
¿Qué puedes hacer con el elemento Canvas en JavaScript según el contenido de w3docs.com?
¿Qué puedes hacer con el elemento Canvas en JavaScript según el contenido de w3docs.com?
Was this page helpful?