En este post voy a explicar y a dar algunos ejemplos para convertir el contenido de una página web a una imagen, es decir, tomarle una “captura de pantalla” a la página web usando únicamente JavaScript del lado del cliente y la maravillosa librería de html2canvas.
Voy a mostrar cómo adjuntar el elemento canvas al documento, descargar la imagen, ignorar algunos elementos al tomar la captura de pantalla, respetar los estilos CSS y poner el resultado sobre un canvas existente.

La imagen anterior fue generada por esta librería, respetando estilos de la tabla, imágenes, colores, fuentes y más.
El funcionamiento de esta librería es sencillo: lee todo el DOM, es decir, todo el documento HTML y construye una representación del mismo en un elemento canvas, leyendo los estilos y formas que tiene. Los resultados, si bien no son siempre perfectos, son bastante aceptables.
Citando al autor:
En otras palabras, no toma realmente una captura de pantalla de la página, sino que construye una representación de la misma en función de las propiedades que lee del DOM.
Después de tener el elemento canvas podemos adjuntarlo a la página web o convertirlo a imagen.
Nota: todos los ejemplos que expondré puedes probarlos aquí, y el código completo de todos y cada uno están en mi GitHub. Tal vez en ocasiones me salte algún fragmento de código, pero puedes revisar el repositorio y ahí estará todo lo necesario.
Incluir librería
Incluye la librería de html2canvas como un script normal. Puedes descargarlo por tu cuenta, en la página oficial hay dos enlaces, uno a la versión normal y otro a la minificada, la normal es para que analices el código y la minificada lista para ser usada en producción.
También puedes incluirla desde jsdelivr como lo hago en los ejemplos:
<!--
Cargar el script de html2canvas, podría ser desde un servidor
propio o como yo lo hago: desde jsdelivr
-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.1/dist/html2canvas.min.js"></script>
Al final todo queda en el tipo de aplicación que hagas.
Capturas de pantalla con JavaScript: primer vistazo
Veamos un primer ejemplo. Para capturar la página web llamamos a la función html2canvas
pasándole un elemento HTML.
Este elemento puede ser document.body
o cualquier otro obtenido, por ejemplo, con querySelector
.
/**
* Ejemplo 1 de html2canvas para convertir el HTML de una web
* a un elemento canvas y adjuntarlo al contenido actual
*
* @author parzibyte
*/
//Definimos el botón para escuchar su click, y también el contenedor del canvas
const $boton = document.querySelector("#btnCapturar"), // El botón que desencadena
$objetivo = document.querySelector("#contenedor"), // A qué le tomamos la foto
$contenedorCanvas = document.querySelector("#contenedorCanvas"); // En dónde ponemos el elemento canvas
// Agregar el listener al botón
$boton.addEventListener("click", () => {
html2canvas($objetivo) // Llamar a html2canvas y pasarle el elemento
.then(canvas => {
// Cuando se resuelva la promesa traerá el canvas
$contenedorCanvas.appendChild(canvas); // Lo agregamos como hijo del div
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Tomar captura de página web</title>
</head>
<body>
<!--
En este caso le "tomamos" la foto al div. Podría ser a un div o
a cualquier elemento HTML
-->
<div id="contenedor">
<h1>Tomar captura de pantalla con html2canvas</h1>
<a href="https://parzibyte.me/blog/" target="_blank">By Parzibyte</a>
<p>Estamos probando la conversión de HTML a una imagen con html2canvas</p>
<img style="max-width: 100%;" src="cosmos-4112660_1280.jpg">
</div>
<!--
El botón no aparece porque está fuera del div
-->
<button id="btnCapturar">Tomar captura</button>
<!--
En este elemento vamos a poner al canvas que será generado.
-->
<div id="contenedorCanvas" style="border: 1px solid red;">
</div>
<!--
Cargar el script de html2canvas, podría ser desde un servidor
propio o como yo lo hago: desde jsdelivr
-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.1/dist/html2canvas.min.js"></script>
<!--
Después de eso, cargar el script que contiene nuestra lógica
-->
<script src="script.js"></script>
</body>
</html>
html2canvas devolverá una promesa que, al resolverse, traerá un elemento canvas
. Ese elemento podemos montarlo en el documento o convertirlo a imagen.
Puedes probar el ejemplo aquí.
Tomar captura respetando estilos CSS
La librería soporta muy bien los estilos del documento. En el siguiente ejemplo uso los estilos de Bulma CSS y agrego una notificación y una tabla.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Tomar captura de página web</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css" />
</head>
<body>
<!--
En este caso le "tomamos" la foto al div. Podría ser a un div o
a cualquier elemento HTML
-->
<div id="contenedor">
<h1 class="is-size-1">Tomar captura de pantalla con html2canvas</h1>
<a href="https://parzibyte.me/blog/" target="_blank">By Parzibyte</a>
<div class="notification is-primary">
<p>Estamos probando la conversión de HTML a una imagen con html2canvas</p>
</div>
<table class="table is-bordered">
<thead>
<tr>
<th>Nombre</th>
<th>Versión</th>
</tr>
</thead>
<tbody>
<tr>
<td>KitKat</td>
<td>4.4</td>
</tr>
<tr>
<td>Lollipop</td>
<td>5</td>
</tr>
<tr>
<td>Marshmallow</td>
<td>6</td>
</tr>
<tr>
<td>Nougat</td>
<td>7</td>
</tr>
<tr>
<td>Oreo</td>
<td>8</td>
</tr>
<tr>
<td>Pie</td>
<td>9</td>
</tr>
</tbody>
</table>
<img style="max-width: 100%;" src="cosmos-4112660_1280.jpg">
</div>
<!--
El botón no aparece porque está fuera del div
-->
<button id="btnCapturar">Tomar captura</button>
<!--
En este elemento vamos a poner al canvas que será generado.
-->
<div id="contenedorCanvas" style="border: 1px solid red;">
</div>
<!--
Cargar el script de html2canvas, podría ser desde un servidor
propio o como yo lo hago: desde jsdelivr
-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.1/dist/html2canvas.min.js"></script>
<!--
Después de eso, cargar el script que contiene nuestra lógica
-->
<script src="script.js"></script>
</body>
</html>
Puedes probarlo aquí.
Capturar todo el cuerpo
En los ejemplos anteriores capturamos un div, no todo el cuerpo. Si queremos capturar todo el cuerpo simplemente pasamos document.body
a html2canvas
.
/**
* Ejemplo 3 de html2canvas para convertir el HTML de una web
* a un elemento canvas - Capturar todo el cuerpo del HTML, no solo un div
*
* @author parzibyte
*/
//Definimos el botón para escuchar su click, y también el contenedor del canvas
const $boton = document.querySelector("#btnCapturar"), // El botón que desencadena
$objetivo = document.body, // A qué le tomamos la foto
$contenedorCanvas = document.querySelector("#contenedorCanvas"); // En dónde ponemos el elemento canvas
// Agregar el listener al botón
$boton.addEventListener("click", () => {
html2canvas($objetivo) // Llamar a html2canvas y pasarle el elemento
.then(canvas => {
// Cuando se resuelva la promesa traerá el canvas
$contenedorCanvas.appendChild(canvas); // Lo agregamos como hijo del div
});
});
Pruébalo aquí.
Si quieres ignorar algunos elementos más tarde veremos cómo hcaerlo.
Descargar imagen generada
Si no te interesa el elemento canvas y quieres una imagen PNG entonces hay que aplicar algunos trucos para convertir el canvas a imagen, lo cual ya expliqué anteriormente.
El código es el siguiente:
/**
* Ejemplo 4 de html2canvas para convertir el HTML de una web
* a un elemento canvas - Descargar la captura como imagen PNG
*
* @author parzibyte
*/
//Definimos el botón para escuchar su click
const $boton = document.querySelector("#btnCapturar"), // El botón que desencadena
$objetivo = document.body; // A qué le tomamos la fotocanvas
// Nota: no necesitamos contenedor, pues vamos a descargarla
// Agregar el listener al botón
$boton.addEventListener("click", () => {
html2canvas($objetivo) // Llamar a html2canvas y pasarle el elemento
.then(canvas => {
// Cuando se resuelva la promesa traerá el canvas
// Crear un elemento <a>
let enlace = document.createElement('a');
enlace.download = "Captura de página web - Parzibyte.me.png";
// Convertir la imagen a Base64
enlace.href = canvas.toDataURL();
// Hacer click en él
enlace.click();
});
});
De esta manera no podemos el canvas en el cuerpo ni en un contenedor, sino que simplemente descargamos la imagen y la guardamos como PNG.
Prueba el ejemplo de descarga de imagen aquí.
Ignorar algunos elementos al tomar la captura
La librería html2canvas permite ignorar algunos elementos a través de una función que se especifica en las opciones.
Esta función recibe el argumento del elemento HTML que está a punto de renderizarse. Si regresamos true
, el elemento se va a ignorar. Si no, el elemento se renderiza.
En el ejemplo se ignoran los elementos de imagen y encabezados, pero podríamos hacer una selección más precisa por clases, ids, etcétera; ya que tenemos al elemento completo.
/**
* Ejemplo 5 de html2canvas para convertir el HTML de una web
* a un elemento canvas - Ignorar algunos elementos al tomar la captura
*
* Nota: también puedes agregar el atributo data-html2canvas-ignore al elemento en cuestión
*
* @author parzibyte
*/
//Definimos el botón para escuchar su click, y también el contenedor del canvas
const $boton = document.querySelector("#btnCapturar"), // El botón que desencadena
$objetivo = document.querySelector("#contenedor"), // A qué le tomamos la foto
$contenedorCanvas = document.querySelector("#contenedorCanvas"); // En dónde ponemos el elemento canvas
// Agregar el listener al botón
$boton.addEventListener("click", () => {
const opciones = {
ignoreElements: elemento => {
// Una función que ignora elementos. Regresa true si quieres que
// el elemento se ignore, y false en caso contrario
const tipo = elemento.nodeName.toLowerCase();
// Si es imagen o encabezado h1, ignorar
if (tipo === "img" || tipo === "h1") {
return true;
}
// Para todo lo demás, no ignorar
return false
}
};
html2canvas($objetivo, opciones) // Llamar a html2canvas y pasarle el elemento
.then(canvas => {
// Cuando se resuelva la promesa traerá el canvas
$contenedorCanvas.appendChild(canvas); // Lo agregamos como hijo del div
});
});
Por cierto, la documentación dice que si ponemos el atributo data-html2canvas-ignore
a un elemento, el mismo será ignorado.
Prueba el código aquí.
Colocar captura de pantalla en canvas existente
Si ya tenemos un canvas definido, podemos poner la captura de pantalla tomada con html2canvas sobre el mismo, usando las opciones.
Específicamente indicamos la clave “canvas” en las opciones, el valor debe ser un elemento HTML de canvas.
/**
* Ejemplo 6 de html2canvas para convertir el HTML de una web
* a un elemento canvas - Poner resultado sobre canvas existente
*
* @author parzibyte
*/
//Definimos el botón para escuchar su click, y también el contenedor del canvas
const $boton = document.querySelector("#btnCapturar"), // El botón que desencadena
$objetivo = document.querySelector("#contenedor"), // A qué le tomamos la foto
$canvas = document.querySelector("#canvas"); // En dónde ponemos el resultado (debe ser un canvas)
// Agregar el listener al botón
$boton.addEventListener("click", () => {
const opciones = {
canvas: $canvas, // Indicar el elemento HTML
};
html2canvas($objetivo, opciones) // Llamar a html2canvas y pasarle el elemento con las opciones
.then(canvas => {
// Aquí ha terminado y ha puesto resultado en el canvas que le indicamos
});
});
Pruébalo aquí.
Conclusión
Solo resta decir que esta librería es muy poderosa y útil en varios aspectos. Te dejo un enlace a la documentación oficial para las opciones, en donde puedes ver cómo cambiar el color de fondo, cortar el canvas, etcétera.
Muy pronto traeré algunos otros ejemplos de esta librería, te invito a suscribirte al blog y seguirme en todas las redes.