HTML2Canvas does not render full div, only what is visible on screen?

JavascriptHtml2canvas

Javascript Problem Overview


I'm trying to use HTML2Canvas to render the contents of a div. Here is the code:

var htmlSource = $('#potenzial-page')[0];
	
$('#btn').on("click", function() {			
	
	html2canvas(htmlSource).then(function(canvas) {
		var img = canvas.toDataURL();
        window.open(img);
	});

});

I'm using v5 beta 3.

When this code runs, it only renders what is visible on the screen. The #potenzial-page div is essentially the entire page, minus the header and footer. All content in this div is visible by scrolling (there are some hidden elements, but I do not want the hidden elements visible in the image.)

I cannot find what's wrong or why it won't save the entire div. I should also note that it appears the image is as tall as the div but only partially visible.

To give an example of what I mean, here is a comparison:

enter image description here

The left is how HTML2Canvas should render the div. The right shows how it renders when it runs the code above. The right image is what's visible in my browsers screen.

I did try adding the height option but it doesn't make a difference.

UPDATE

If I scroll to the very top of the page then run the script it will render the entire div as it should.

How do I render the div without having to scroll to the top?

Javascript Solutions


Solution 1 - Javascript

I hope thet help you

html2canvas(htmlSource, {scrollY: -window.scrollY}).then(function(canvas) {
            var img = canvas.toDataURL();
            window.open(img);
        });

Solution 2 - Javascript

A solution that worked for me was to add the following to my css:

.html2canvas-container { width: 3000px !important; height: 3000px !important; }

It prevents html2canvas from limiting the rendering to the viewable area (which seems to be the default).

See here: https://github.com/niklasvh/html2canvas/issues/117

Solution 3 - Javascript

I used window.scrollTo()in my case and it worked for me.

Below is a sample code

$('#btn').on("click", function() { 
    window.scrollTo(0,0);     
    html2canvas(htmlSource).then(function(canvas) {
        var img = canvas.toDataURL();
        window.open(img);
    });
    window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
});

Solution 4 - Javascript

You can add in scroll position as a variable in html2canvas which removes the need to scroll the page.

html2canvas(document.querySelector("#your-element"), { scrollX: 0, scrollY: 0 }).then(function(canvas) {

Solution 5 - Javascript

I just did something like this and it worked for me:

html2canvas(document.querySelector("#capture2image"), {
            allowTaint: true,
            useCORS: true,
            logging: false,
            height: window.outerHeight + window.innerHeight,
            windowHeight: window.outerHeight + window.innerHeight, 

Solution 6 - Javascript

enter image description here

If you have a height set to the div you want to turn to a canvas - you need to remove that before actually taking the snapshot. Otherwise it will just cut it off because of that height.

 $(".yourElemThatHasSomeHeightSet").css("height", "");

Then you will notice that scrolling down - will still cut your document. Simply do a:

$("html, body").scrollTop(0);

before taking the snapshot.

Solution 7 - Javascript

This is how I've achieved in Reactjs.

Main problem were ratio and scale If you do a quick window.devicePixelRatio, it's default value is 2 which was causing the half image issue.

const printDocument = () => {
  const input = document.getElementById('divToPrint');
  const divHeight = input.clientHeight
  const divWidth = input.clientWidth
  const ratio = divHeight / divWidth;

  html2canvas(input, { scale: '1' }).then((canvas) => {
    const imgData = canvas.toDataURL('image/jpeg');
    const pdfDOC = new jsPDF("l", "mm", "a0"); //  use a4 for smaller page

    const width = pdfDOC.internal.pageSize.getWidth();
    let height = pdfDOC.internal.pageSize.getHeight();
    height = ratio * width;

    pdfDOC.addImage(imgData, 'JPEG', 0, 0, width - 20, height - 10);
    pdfDOC.save('summary.pdf');   //Download the rendered PDF.
  });
}

Solution 8 - Javascript

  window.scrollTo(0,0);  

Add this works for me.

Solution 9 - Javascript

for people dont wanna hacky a way for scroll problem.: dom-to-image

  1. you can scroll while you are snapshotting image
  2. and its much more faster (70x according to this blog ).

blog: https://betterprogramming.pub/heres-why-i-m-replacing-html2canvas-with-html-to-image-in-our-react-app-d8da0b85eadf

in the blog it mentions html-to-image. it is fork of dom-2-image. i used dom-to-image (ancestor , original one).

var node = document.getElementById('my-node');

domtoimage.toPng(node)
    .then(function (dataUrl) {
        var img = new Image();
        img.src = dataUrl;
        document.body.appendChild(img);
    })
    .catch(function (error) {
        console.error('oops, something went wrong!', error);
    });

Solution 10 - Javascript

The following code worked for me:

      window.scrollTo(0, 0);

      html2canvas(htmlRef, {
        scrollX: -window.scrollX,
        scrollY: -window.scrollY,
        windowWidth: document.documentElement.offsetWidth,
        windowHeight: htmlRef.scrollHeight,
      }).then((canvas) => {
        const img = new Image();

        const imgData = canvas
          .toDataURL("image/png")
          .replace("image/png", "image/octet-stream");

        const pdf = new jsPDF("p", "mm", "a4");
        const imgProps = pdf.getImageProperties(imgData);
        const pdfWidth = pdf.internal.pageSize.getWidth();
        const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
        pdf.addImage(imgData, "JPEG", 0, 0, pdfWidth, pdfHeight);
        pdf.save();
      });

Solution 11 - Javascript

Another React Approach...

On your submit button on click set the document height dynamically, then call html2canvas using document.body as the first argument

<button onClick={() => {
var body = document.body,
html = document.documentElement;

var height = Math.max(body.scrollHeight, body.offsetHeight,
             html.clientHeight, html.scrollHeight, html.offsetHeight);
             document.body.style.height = `${height}px`

html2canvas(document.body).then(function (canvas) {
                var imgData = canvas.toDataURL('image/pdf')
                var doc = new jsPDF('p', 'mm', [canvas.width, canvas.height])
                doc.addImage(imgData, 'PDF', 10, 10, canvas.width, canvas.height)
                doc.save('name-of-pdf.pdf')
              });
}}>Submit</button>

This will set the html height of public/index.html which html2canvas seems to render from (i.e. not the "root" div).

Solution 12 - Javascript

This works for me:

  const input = document.getElementById('fragmentForPDF');
  
  // This row fixed problem
  input.parentNode.style.overflow = 'visible';

  html2canvas(input)...

Solution 13 - Javascript

window.scrollTo(0, 0); // this will help to print if div hidden or on mobile screen

html2canvas(document.getElementById("my_div_img")).then(function (canvas) 
                 {
                    //for give white BG
                    var context = canvas.getContext('2d');
                    context.save();
                    context.globalCompositeOperation = 'destination-over';
                    context.fillStyle = "rgb(255, 255, 255)";
                    context.fillRect(0, 0, canvas.width, canvas.height);
                    context.restore();
                    var imgData = canvas.toDataURL('image/jpeg', 1);
                    //console.log(imgData);
}

Solution 14 - Javascript

This worked for me:

html2canvas(el, {
	width: el.scrollWidth,
    height: el.scrollHeight,
})

See here for the source.

Solution 15 - Javascript

<div #potentialContainer id="potentialContainer" class="potentialContainer" style="height: auto;">
some large content here--------------------
</div>

import html2canvas from 'html2canvas';

downloadImage() {

html2canvas(document.querySelector('#potentialContainer'), {
  logging: true,
  allowTaint: false,
  useCORS: true,
  width: document.querySelector('#potentialContainer').scrollWidth,
  height: section.scrollHeight,
  scrollX: -window.scrollX,
  scrollY: -window.scrollY,
}).then((canvas) => {
  var imgWidth = 210;
  var pageHeight = 290;
  var imgHeight = canvas.height * imgWidth / canvas.width;
  var heightLeft = imgHeight;


  var doc = new jsPDF('p', 'mm');
  var position = 0;
  var pageData = canvas.toDataURL('image/jpeg', 1.0);
  var imgData = encodeURIComponent(pageData);
  doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
  doc.setLineWidth(5);
  doc.setDrawColor(255, 255, 255);
  doc.rect(0, 0, 210, 295);
  heightLeft -= pageHeight;

  while (heightLeft >= 0) {
    position = heightLeft - imgHeight;
    doc.addPage();
    doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
    doc.setLineWidth(5);
    doc.setDrawColor(255, 255, 255);
    doc.rect(0, 0, 210, 295);
    heightLeft -= pageHeight;
  }
  doc.save('file.pdf');

 });
 }

Note:- It is important to add style height:auto

The above code will convert a large image to a multipage pdf

Solution 16 - Javascript

document.getElementById("dld_report").addEventListener("click", function() {
    // Make sure the area you want to take screenshot is visible in CSS
    document.querySelector('#boundary').style.overflow = 'visible'; 
     
    html2canvas(document.querySelector('#boundary'), {
      // Set the height of screenshot image same as page hieght
      height: window.outerHeight + window.innerHeight,
    }).then(function(canvas) {
        saveAs(canvas.toDataURL(), 'report.png');
    });
});
// dld_report -> button to trigger the screenshot

Set style overflow = "visible" and height were the key to make this happen.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionL84View Question on Stackoverflow
Solution 1 - JavascriptРоман СлабікView Answer on Stackoverflow
Solution 2 - JavascriptjbgtView Answer on Stackoverflow
Solution 3 - JavascriptAmit AnandView Answer on Stackoverflow
Solution 4 - JavascriptKaiser47View Answer on Stackoverflow
Solution 5 - JavascriptRicky LeviView Answer on Stackoverflow
Solution 6 - JavascriptNSPView Answer on Stackoverflow
Solution 7 - JavascriptPriyanshu ChauhanView Answer on Stackoverflow
Solution 8 - JavascriptAri AbimanyuView Answer on Stackoverflow
Solution 9 - Javascriptbh_earth0View Answer on Stackoverflow
Solution 10 - JavascriptSai Teja TView Answer on Stackoverflow
Solution 11 - JavascriptPaul SenderView Answer on Stackoverflow
Solution 12 - JavascriptRuslan ValeevView Answer on Stackoverflow
Solution 13 - JavascriptajmiraniView Answer on Stackoverflow
Solution 14 - JavascriptTingnoyChannelView Answer on Stackoverflow
Solution 15 - JavascriptShijuView Answer on Stackoverflow
Solution 16 - JavascriptJaz PinView Answer on Stackoverflow