W3docs

Etiqueta HTML <canvas>

La etiqueta HTML <canvas> define un área para dibujar gráficos, formas, texto y animaciones con JavaScript. Aprende su tamaño, accesibilidad y canvas vs SVG.

La etiqueta <canvas> es uno de los elementos HTML5. Define un área en la página web donde podemos crear diferentes objetos, imágenes, animaciones y composiciones fotográficas mediante scripts (normalmente JavaScript). Debes usar un script para dibujar gráficos, ya que la etiqueta <canvas> es simplemente un contenedor para los gráficos.

Al trabajar con canvas, es importante distinguir entre conceptos como el elemento canvas y el contexto de un elemento, que a menudo se confunden. El elemento es lo que está integrado en HTML (el nodo del DOM). Un contexto de canvas es un objeto con sus propiedades y métodos de renderizado. El contexto puede ser 2D o 3D. El elemento canvas solo puede tener un contexto.

Debes proporcionar contenido alternativo dentro de la etiqueta <canvas> para que los navegadores más antiguos que no admiten canvas, los navegadores con JavaScript desactivado y los lectores de pantalla tengan algo significativo que mostrar (consulta Accesibilidad más abajo).

Puedes usar CSS para cambiar el tamaño mostrado del canvas, pero es mejor establecer la resolución con los atributos width y height en <canvas> — ya sea en el HTML o desde JavaScript — para evitar un mapa de bits borroso o estirado.

De forma predeterminada, un elemento <canvas> tiene un tamaño de 300x150 píxeles.

Canvas vs. SVG: ¿cuál deberías usar?

Tanto <canvas> como <svg> dibujan gráficos en el navegador, pero funcionan de maneras fundamentalmente distintas:

  • Canvas está basado en píxeles (modo inmediato). Una vez que dibujas algo, se convierte en un mapa de bits plano: el navegador no conserva memoria de las formas individuales. No existe un DOM para el contenido dibujado, por lo que no puedes asociar escuchadores de eventos a una forma; para "mover" un círculo debes limpiar y redibujar toda la escena en cada fotograma.
  • SVG está basado en formas (modo retenido). Cada elemento permanece en el DOM, puede estilizarse con CSS, manipularse con scripts y es independiente de la resolución (se mantiene nítido a cualquier nivel de zoom).

Usa canvas cuando redibujues con frecuencia o tengas muchos objetos: juegos, efectos de partículas, visualización de datos en tiempo real, procesamiento de imágenes. Usa SVG cuando tengas un número moderado de formas que deban ser interactivas, accesibles o escaladas sin pérdida: iconos, gráficas, diagramas. Como regla general, canvas destaca en muchos píxeles cambiando rápido, y SVG en menos formas que permanecen interactivas.

Tamaño: los atributos width/height vs. CSS

Este es el error más común con canvas. Un canvas tiene dos tamaños:

  • Los atributos width y height establecen el tamaño del búfer de dibujo (su resolución en píxeles del mapa de bits).
  • CSS width/height establece el tamaño mostrado en la página.

Si difieren, el navegador estira el mapa de bits para ajustarse al bloque CSS, lo que desenfoca o distorsiona tu dibujo. Establece siempre los atributos a la resolución con la que dibujas; usa CSS para posicionar el elemento solo si coincide.

<!-- Good: drawing buffer matches what you draw -->
<canvas width="400" height="200"></canvas>

<!-- Risky: CSS stretches a default 300x150 bitmap to 600x300, blurring it -->
<canvas style="width: 600px; height: 300px;"></canvas>

Para una salida nítida en pantallas de alta densidad de píxeles ("Retina"), escala el búfer con window.devicePixelRatio (por ejemplo, establece los atributos a cssWidth * devicePixelRatio) y luego llama a ctx.scale(dpr, dpr) antes de dibujar.

Sintaxis

La etiqueta <canvas> va en pares. El contenido se escribe entre las etiquetas de apertura (<canvas>) y cierre (</canvas>).

Ejemplo de la etiqueta HTML <canvas>:

El script de abajo obtiene el elemento con document.getElementById() y llama a getContext('2d') para obtener el contexto de dibujo 2D: el objeto que contiene todos los métodos y propiedades de dibujo. Al establecer fillStyle se elige el color de relleno, y fillRect(x, y, width, height) pinta un rectángulo relleno cuya esquina superior izquierda está en (x, y). Las coordenadas de canvas comienzan en (0, 0) en la esquina superior izquierda, con x aumentando hacia la derecha e y aumentando hacia abajo.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head> 
  <body>
    <canvas id="canvasExample">Your browser doesn’t support the HTML5 canvas element.</canvas>
    <script>
      const c = document.getElementById('canvasExample');
      const ctx = c.getContext('2d');
      ctx.fillStyle = '#1c87c9';
      ctx.fillRect(10, 50, 80, 80);
    </script>
  </body>
</html>

Resultado

canvas exemple

Ejemplo de la etiqueta HTML <canvas> para texto:

Para dibujar texto debes establecer la propiedad font (con la misma sintaxis que la propiedad abreviada font de CSS) y fillStyle para el color, y luego llamar a fillText(text, x, y). El punto (x, y) aquí es la posición de la línea base del texto, no su esquina superior izquierda. Ten en cuenta que width y height se establecen como atributos en el elemento para que el búfer de dibujo coincida con el área en la que dibujamos.

<!DOCTYPE HTML>
<html>
  <head>
    <title>Title of the document</title>
  </head> 
  <body>
    <canvas id="canvasExample" width="400" height="200"></canvas>
    <script>
      const canvas = document.getElementById('canvasExample');
      const context = canvas.getContext('2d');
      context.font = '30pt Calibri';
      context.fillStyle = '#1c87c9';
      context.fillText('Canvas Example !', 50, 100);
    </script>
  </body>
</html>

Ejemplo de la etiqueta HTML <canvas> para trazar una línea:

Las líneas y otros trazados se dibujan en tres pasos. moveTo(x, y) levanta el "lápiz" y lo coloca en un punto de inicio sin dibujar. lineTo(x, y) añade un segmento recto desde el punto actual hasta el nuevo punto, pero aún no se pinta nada. Solo stroke() renderiza realmente el trazado, usando el strokeStyle actual (el color del contorno). Cuando dibujas más de un trazado separado, comienza cada uno con beginPath(); de lo contrario, los nuevos segmentos se añaden al trazado anterior. Usa fill() (con fillStyle) en lugar de stroke() cuando quieras un trazado relleno en vez de contorneado.

<!DOCTYPE html>
<html>
  <body>
    <canvas width="300" height="150" style="border:1px solid #cccccc;" id="canvasExample">
      Your browser does not support the HTML5 canvas tag.
    </canvas>
    <script>
      const c = document.getElementById("canvasExample");
      const ctx = c.getContext("2d");
      ctx.beginPath();
      ctx.moveTo(0, 0);
      ctx.lineTo(300, 150);
      ctx.strokeStyle = '#1c87c9';
      ctx.stroke();
    </script>
  </body>
</html>

Casos de uso comunes

Más allá de las formas simples, el contexto 2D te permite crear gráficos enriquecidos:

  • Animación — limpia el canvas y redibuja dentro de un bucle requestAnimationFrame() para producir movimiento suave fotograma a fotograma.
  • Imágenesctx.drawImage(img, x, y) pinta un <img>, otro canvas o un fotograma de vídeo, lo que es la base de la edición de fotos y los filtros.
  • GradientescreateLinearGradient() y createRadialGradient() producen rellenos y trazos degradados.
  • Juegos y visualización de datos — canvas es la opción preferida cuando hay que repintar muchos objetos en cada fotograma, razón por la cual las bibliotecas de gráficas y juegos se construyen sobre él.

Todo esto depende de JavaScript, por lo que un buen dominio del HTML DOM te ayudará a sacar el máximo partido de canvas.

Accesibilidad

La salida de canvas son solo píxeles: los lectores de pantalla y otras tecnologías de asistencia no pueden "ver" lo que has dibujado. Haz que el contenido de canvas sea accesible:

  • Proporciona contenido alternativo significativo entre las etiquetas. Todo lo que esté dentro de <canvas>...</canvas> se muestra a los navegadores sin soporte de canvas y queda expuesto a la tecnología de asistencia, así que describe el dibujo en lugar de escribir un mensaje genérico de "no compatible".
  • Para un dibujo estático, añade role="img" y un aria-label (o aria-labelledby) que lo describa, p. ej. <canvas role="img" aria-label="Bar chart of 2024 sales">.
  • Para canvas interactivos, refleja los controles y el estado en elementos del DOM reales (botones, regiones en vivo), ya que las formas dibujadas no son enfocables ni legibles.

Atributos

AtributoValorDescripción
heightpíxelesDefine la altura del elemento en píxeles.
widthpíxelesDefine el ancho del elemento en píxeles.

La etiqueta <canvas> admite los Atributos Globales y los Atributos de Evento.

Práctica

Práctica
¿Qué método devuelve el objeto sobre el que se llaman los comandos de dibujo como fillRect() y stroke()?
¿Qué método devuelve el objeto sobre el que se llaman los comandos de dibujo como fillRect() y stroke()?
Práctica
Dibujas en un canvas de 300x150 pero estableces su tamaño a 600px con CSS. ¿Qué ocurre?
Dibujas en un canvas de 300x150 pero estableces su tamaño a 600px con CSS. ¿Qué ocurre?
Was this page helpful?