Html2Canvas image is getting cut
Asked Answered
F

7

13

I use Html2Canvas and then jsPdf to export the image.

This is the function:

function exportPdf() {
    content = $("#print");

    var useWidth = content.prop('scrollWidth');
    var useHeight = content.prop('scrollHeight');

    debugger;

    html2canvas((content), { width: useWidth, height: useHeight}).then(function (canvas) {
        debugger;
        var img = canvas.toDataURL("image/png");
        var doc = new jsPDF({
            unit:'px', 
            format:'a4'
        });

        debugger;
        doc.addImage(img, 'JPEG', 0, 0);
        doc.save('test.pdf');
    });
}

I think is taking in consideration the viewport, is like doing a printscreen, of course whatever is below the scroll it doesn't take it into consideration.

Any ideas?

Finicky answered 31/10, 2016 at 19:19 Comment(0)
A
23

Call

    window.scrollTo(0,0)

Before calling html2canvas, its seems its a bug but the window needs to be at the top for html2canvas to capture the entire DOM passed to it

Anagnorisis answered 20/9, 2017 at 16:45 Comment(1)
Not very nice from a UX perspective, but this trick actually works, so thanks for sharing it! :DYeung
N
10

It happens when window is scrolled. To work around this problem you can pass negative of whatever window is scrolled by.

html2canvas(htmlSource, {scrollY: -window.scrollY}).then(function(canvas) {

// Do Something here

});
Natashianatassia answered 12/4, 2020 at 20:1 Comment(0)
N
3

One of the reason is already mentioned above that is window might be scrolled, so always add this line before u capture image using html2canvas

    window.scrollTo(0,0)

Another problem can be the resolution of image is more than a pdf page, for that you need to get the width and height of PDF document.

var width = doc.internal.pageSize.getWidth();
var height = doc.internal.pageSize.getHeight();

Use it for your image to fit the PDF document.

doc.addImage(imgData, 'JPEG', 0, 0, width, height);

If you want a dynamic sized image not to be distorted and keep the image width/height ratio

 var width = doc.internal.pageSize.getWidth();
 var height = doc.internal.pageSize.getHeight();

 let widthRatio = width / canvas.width;
 let heightRatio = height / canvas.height;

 let ratio = widthRatio > heightRatio ? heightRatio : widthRatio

Followed by

 doc.addImage(imgData, "PNG", 0, 0, canvas.width * ratio, canvas.height * ratio,);
Null answered 23/7, 2020 at 0:18 Comment(0)
O
3

Setting windowHeight and height worked for me:

Try like this:

html2canvas(htmlSource, {
     height: window.outerHeight + window.innerHeight,
     windowHeight: window.outerHeight + window.innerHeight,
     scrollY: -window.scrollY
}).then(function(canvas) {
    // Do Something here    
});
Outlander answered 25/1, 2021 at 7:43 Comment(0)
H
1

You can try something with the responsive way like :

if (screen.width < 1024) {
    document
      .querySelector("meta[name=viewport]")
      .setAttribute("content", "width=1200px");
  }

  let generatedPDFB64;
  //used the Printable HOC for capturing printable component with print-id attribute
  const printElement = document.querySelector(`div[print-id=${selector}]`);
  // convert the html to canvase
  const convertedCanvas = await html2canvas(printElement, {
    allowTaint: true,
    removeContainer: true,
    backgroundColor: null,
    imageTimeout: 15000,
    logging: true,
    scale: 2,
    scrollY: window.scrollTo({
      top: 0,
      behavior: 'smooth'
    }),
    useCORS: true
  });

  const contentDataURL = convertedCanvas.toDataURL("image/png");
  const imgWidth = 205;
  const pageHeight = 300;
  const imgHeight = (convertedCanvas.height * imgWidth) / convertedCanvas.width;
  let heightLeft = imgHeight;
  const shouldCompress = true

  let pdf = new jsPDF("p", "mm", "a4", shouldCompress); // A4 size page of PDF
  let position = 0;

   pdf.addImage(
    contentDataURL,
    "PNG",
    0,
    position,
    imgWidth,
    imgHeight,
    "print",
    "FAST"
  ); 
  heightLeft -= pageHeight;

  while (heightLeft >= 0) {
    position = heightLeft - imgHeight;
    pdf.addPage();
    pdf.addImage(
      convertedCanvas,
      0,
      position,
      imgWidth,
      imgHeight,
      "print",
      "FAST"
    );
    heightLeft -= pageHeight;
  }

  pdf.save("resume.pdf"); // Generated PDF

  if (screen.width < 1024) {
    document
      .querySelector("meta[name=viewport]")
      .setAttribute("content", "width=device-width, initial-scale=1");
  }

Hazel answered 21/9, 2021 at 7:57 Comment(0)
T
0

The only thing that worked for me, was to add the following code into my css.

This style code is used to prevent html2canvas limit the rendering to the viewable area.

.html2canvas-container { 
    width: 3000px; 
    height: 3000px; 
}
Thuythuya answered 23/5, 2021 at 12:12 Comment(0)
A
0

For my case, I added a class to make it fixed:

$("#print").addClass('ready-fix');

CSS:

.ready-fix {
    position: fixed !important;
    top: 0;
    left: 50%;
    z-index: 9999;
    -ms-transform: translate(-50%, 0);
    transform: translate(-50%, 0);
}

Then called "html2canvas", the image was no longer cropped:

html2canvas(document.querySelector("#print"), { scale: window.devicePixelRatio, allowTaint: true }).then(canvas => {
//code here
$("#print").removeClass('ready-fix');
})

Finally removed the fixed class.

Azpurua answered 27/12, 2022 at 8:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.