niklasvh / html2canvas

Screenshots with JavaScript
https://html2canvas.hertzen.com/
MIT License
30.69k stars 4.82k forks source link

HTML2canvas troubles on mobile devices #2883

Open WInzelrac opened 2 years ago

WInzelrac commented 2 years ago

Hey, I've used HTML2canvas and jsPDF to create a pdf of a form and save it. My problem is : It works perfectly fine on a computer, but on mobile devices like iPad or phones (apple or android), the canvas created is blank. It has the size the canvas should have but totally empty. So, I wonder if their is a config i've missed or anything. Thanks.

Here is my code :

download.addEventListener("click", function() {
    console.log('click');
//Create Canvas
      var element = document.getElementById('element-to-print');
      html2canvas(element).then(function (canvas) {
        if (document.querySelector('canvas')==null) {
          document.body.appendChild(canvas);
          // console.log('Canvas créé');
          var canvas = document.querySelector('canvas');
          // canvas.style.display = 'none';
          // console.log('Canvas caché');
          toPdf();
        }else{
          supprCanvas();
          document.body.appendChild(canvas);
          // console.log('Canvas créé');
          // canvas.style.display = 'none';
          // console.log('Canvas caché');
          toPdf();
        }
        //suppression
        function supprCanvas(){
          var canvas = document.querySelector('canvas');
          document.body.removeChild(canvas);
          canvas = document.querySelector('canvas');
          // console.log('Canvas supprimé');
        }
        //Create PDF
        function toPdf(){
          // console.log('post html2canvas');
          var canvas = document.querySelector('canvas');
          var context = canvas.getContext('2d');
          var contentWidth = canvas.width;
              var contentHeight = canvas.height;

              //The height of the canvas which one pdf page can show;
              var pageHeight = contentWidth / 592.28 * 841.89;
              //the height of canvas that haven't render to pdf
              var leftHeight = contentHeight;
              //addImage y-axial offset
              var position = 0;
              //a4 format [595.28,841.89]
                    var imgWidth = 595.28;
              var imgHeight = 592.28/contentWidth * contentHeight;

              var pageData = canvas.toDataURL('image/jpeg', 1.0);

              var pdf = new jsPDF('', 'pt', 'a4');

             if (leftHeight < pageHeight) {
                  pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight );
              } else {
                  while(leftHeight > 0) {
                      pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                      leftHeight -= pageHeight;
                      position -= 841.89;
                      //avoid blank page
                      if(leftHeight > 0) {
                          pdf.addPage();
                      }
                  }
              }
              // console.log('pre pdf save');
              pdf.save('content.pdf');
              // console.log('pdf save');
        }
          })
      });
SaschaDeWaal commented 2 years ago

I have exactly them same problem. On PC it works, but on mobile devices its just blank. Did you manage to find a fix @WInzelrac?

KaterinaLab commented 2 years ago

First of all, if you get error like this "Uncaught (in promise) ReferenceError: jsPDF is not defined" use

window.jsPDF = window.jspdf.jsPDF;
var pdf = new jsPDF('l', 'pt', [PDF_Width, PDF_Height]);

instead of var pdf = new jsPDF('', 'pt', 'a4'); Each browser compiles js code differently. So you could get this error on mobile browser, and don't get it on PC browser.

The rest of your code works for me on PC and mobile devices. Also set css style cursor: pointer; to button, it really helps on iphone.

Also check my code, that works on PC and Mobile.

        var dwn_btn =  document.getElementById('matrix-download');
    if (typeof(dwn_btn) != 'undefined' && dwn_btn != null)
    {
        document.getElementById ("matrix-download").addEventListener ("click", download_pdf, false);
    }

    function download_pdf(){
        $('.matrix-btn-loader').addClass('active');

        var clone = $('#matrix-wrap').clone().addClass('to_download' ).prop('id', '');
        $('body').append(clone);

        var html2canvas_options = {
            scale: 2,
            onclone: function(canvas) {
                $('.matrix-wrap.to_download').remove();
            }
        };

        var HTML_Width = $('.matrix-wrap.to_download').width();
        var HTML_Height = $('.matrix-wrap.to_download').height();
        var top_left_margin = 30;
        var PDF_Width = HTML_Width + (top_left_margin * 2);
        var PDF_Height = HTML_Height + (top_left_margin * 2);

        window.jsPDF = window.jspdf.jsPDF;

        html2canvas($('.matrix-wrap.to_download')[0], html2canvas_options).then(function (canvas) {
            var imgData = canvas.toDataURL("image/jpeg");
            var pdf = new jsPDF('l', 'pt', [PDF_Width, PDF_Height]);

            pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, HTML_Width, HTML_Height);

            $('.matrix-btn-loader').removeClass('active');
            pdf.save(`matrix3.pdf`);                
        });
    }