jquery - the - screenshot javascript html5
Error html2canvas: Error no detectado: IndexSizeError: DOM Exception 1 (4)
Estoy usando html2canvas para convertir un div en un lienzo. Me gusta esto:
<script src="js/libs/jquery-1.7.1.min.js"></script>
<script src="js/libs/jquery-ui-1.8.17.custom.min.js"></script>
<script src="js/html2canvas/html2canvas.js"></script>
...
<body id="body">
<div id="demo">
...
</div>
</body>
<script>
$(''#demo'').html2canvas({
onrendered: function( canvas ) {
var img = canvas.toDataURL()
window.open(img);
}
});
</script>
y obtengo este error: "Error no detectado: IndexSizeError: DOM Exception 1" en html2canvas.js:
ctx.drawImage( canvas, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height );
¿Alguien tiene idea de qué está pasando?
Diría que probablemente tenga algún atributo float
o posición fixed
en un div que haga que un contenedor tenga una altura de 0 mientras que el contenido tiene una altura superior. tuve este problema antes debido a que html2canvas no puede manejar un contenido más grande que su contenedor. por ejemplo, si tienes algo como esto:
<div>
<img url="..." style="float: right;">
</div>
html2canvas generará este error porque div
tiene una altura de 0 mientras que la img
es más grande. La posible corrección será forzar la altura de div para que sea superior a la altura de la imagen.
gracias a Saturnix por su respuesta detallada, me ayudó a descubrir de dónde vino.
Espero que esto te pueda ayudar
Siempre que llame a drawImage
en un lienzo y quiera recortar una imagen, debe drawImage
9 valores.
ctx.drawImage(
imageObject,
sourceX,
sourceY,
sourceWidth,
sourceHeight,
destX,
destY,
destWidth,
destHeight);
¡ahora eso es un montón de cosas! Es realmente fácil cometer errores: para evitarlos, permítanme explicar cómo funciona DrawImage cuando recorta una imagen.
Imagina dibujar un cuadrado en una hoja de papel. La esquina superior izquierda del cuadrado que está dibujando se sourceX
píxels sourceY
y píxels sourceY
donde 0 es la esquina superior izquierda de la hoja de papel. La dimensión en píxeles del cuadrado que está dibujando está definida por sourceWidth
y sourceHeight
.
Todo lo que se encuentre dentro del cuadrado que haya definido se cortará y pegará dentro de su lienzo en la posición (en píxeles) de destX
y destY
(donde 0 es la esquina superior izquierda de su lienzo).
Debido a que no estamos en la vida real, el cuadrado que corte puede estirarse y tener una dimensión diferente. Es por eso que también debe definir destWidth
y destHeight
Aquí hay una representación gráfica de todo esto.
Para volver a su pregunta, Uncaught Error: IndexSizeError: DOM Exception 1
generalmente aparece cuando el cuadrado que está tratando de cortar es más grande que la hoja de papel real, o si está tratando de cortar el papel en una posición donde no existe (como sourceX = -1
, lo cual es imposible por razones obvias).
No tengo idea de qué bounds.left
son. bounds.left
, bounds.top
y los demás, pero estoy 99.9% seguro de que son valores incorrectos. Intente console.log
y compárelos con el objeto de imagen que está proporcionando (en este caso, el lienzo).
console.log(canvas.width);
console.log(canvas.height);
console.log(bounds.left);
console.log(bounds.top);
ecc....
Tuve el mismo problema El problema ocurre cuando traté de usar lienzo dentro de un elemento oculto. En mi caso, estoy usando Bootstrap modal y el lienzo dentro de él.
La solución es: "Implementar códigos canvas después de que el elemento esté completamente visible" .
En mi caso, tengo que usar $(''.modal'').on(''shown.bs.modal'', function(){})
lugar de $(''.modal'').on(''show.bs.modal'', function(){})
, porque el elemento modal aparece por completo en el evento shown.bs.modal
; )
Este es el informe de error html2canvas
.
Pude arreglar el Error no detectado: IndexSizeError: DOM Exception 1 parcheando el archivo html2canvas.js.
reemplazar esto:
ctx.drawImage(canvas, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height);
por esto:
var imgData = canvas.getContext("2d").getImageData(bounds.left, bounds.top, bounds.width, bounds.height);
ctx.putImageData(imgData, 0, 0);