HTML2Canvas 不呈现完整的 div,只呈现屏幕上可见的内容?

Posted

技术标签:

【中文标题】HTML2Canvas 不呈现完整的 div,只呈现屏幕上可见的内容?【英文标题】:HTML2Canvas does not render full div, only what is visible on screen? 【发布时间】:2016-07-12 19:35:10 【问题描述】:

我正在尝试使用 html2Canvas 来呈现 div 的内容。这是代码:

var htmlSource = $('#potenzial-page')[0];

$('#btn').on("click", function()           

    html2canvas(htmlSource).then(function(canvas) 
        var img = canvas.toDataURL();
        window.open(img);
    );

);

我正在使用 v5 beta 3。

当此代码运行时,它只呈现屏幕上可见的内容。 #potenzial-page div 基本上是整个页面,减去页眉和页脚。此 div 中的所有内容通过滚动可见(有一些隐藏元素,但我不希望隐藏元素在图像中可见。)

我找不到问题所在或为什么它不能保存整个 div。我还应该注意到,图像看起来和 div 一样高,但只是部分可见。

举个例子说明我的意思,这里是一个比较:

左边是 HTML2Canvas 应该如何渲染 div。右侧显示了它在运行上面的代码时的呈现方式。正确的图像是在我的浏览器屏幕中可见的。

我确实尝试添加 height 选项,但没有任何区别。

更新

如果我滚动到页面的最顶部然后运行脚本,它将呈现整个 div。

如何在不滚动到顶部的情况下呈现 div?

【问题讨论】:

您是否在 SO 中看到过此解决方案:"Html2canvas converting overflowed content to image" 提出了一种解决方案,将溢出设置为可见,然后渲染,然后隐藏溢出。 我也遇到了同样的问题,你是怎么解决的? 这个问题解决了:github.com/niklasvh/html2canvas/issues/… 【参考方案1】:

对我有用的解决方案是将以下内容添加到我的 css 中:

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

它可以防止 html2canvas 将渲染限制在可视区域(这似乎是默认设置)。

请看这里:https://github.com/niklasvh/html2canvas/issues/117

【讨论】:

你成就了我的一天。 这是最好的解决方案!【参考方案2】:

我使用window.scrollTo()就我而言,它对我有用。

下面是示例代码

$('#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);
);

【讨论】:

这对我来说是一个很好的快速解决方案。如果您不关心滚动到顶部,这可行。 谢谢!效果很好【参考方案3】:

如果您为要转换为画布的 div 设置了高度 - 您需要在实际拍摄快照之前将其删除。否则它会因为那个高度而将其切断。

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

然后您会注意到向下滚动 - 仍会剪切您的文档。 只需做一个:

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

拍摄快照之前。

【讨论】:

【参考方案4】:
  window.scrollTo(0,0);  

添加这个对我有用。

【讨论】:

【参考方案5】:

我刚刚做了这样的事情,它对我有用:

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

【讨论】:

为我工作谢谢 :-)【参考方案6】:

您可以在 html2canvas 中添加滚动位置作为变量,从而无需滚动页面。

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

【讨论】:

完美。谢谢。 未按预期工作。之前它只捕获可见部分,现在它从顶部捕获(很好),但只有一部分等于可见的高度,其余部分为空白。【参考方案7】:

希望对你有帮助

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

【讨论】:

唯一对我有用的答案。 (我的特殊情况是地图仅部分在屏幕外且仅垂直显示。) 谢谢你!我在页面底部有一个按钮,可以将其上方的某些内容转换为图像。这是关键! 干得好。这真的帮助了我【参考方案8】:

这就是我在 Reactjs 中实现的方式。

主要问题是ratioscale 如果您快速执行 window.devicePixelRatio,它的默认值为 2,这会导致半图像问题。

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.
  );

【讨论】:

【参考方案9】:

另一种 React 方法...

在点击提交按钮时动态设置文档高度,然后使用 document.body 作为第一个参数调用 html2canvas

<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 = `$heightpx`

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>

这将设置 html2canvas 似乎从中呈现的 public/index.html 的 html 高度(即不是“根”div)。

【讨论】:

【参考方案10】:

这对我有用:

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

  html2canvas(input)...

【讨论】:

【参考方案11】:
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);

【讨论】:

【参考方案12】:

对于不想破解滚动问题的人来说。:dom-to-image

    您可以在拍摄图像时滚动 而且速度更快(根据此博客,速度为 70 倍)。

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

在博客中提到了 html-to-image。它是 dom-2-image 的分支。我使用 dom-to-image(祖先,原始的)。

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);
    );

【讨论】:

【参考方案13】:

这对我有用:

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

来源见here。

【讨论】:

【参考方案14】:

以下代码对我有用:

      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();
      );

【讨论】:

【参考方案15】:
<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');

 );
 

注意:-添加样式height:auto很重要

以上代码将大图转换为多页pdf

【讨论】:

以上是关于HTML2Canvas 不呈现完整的 div,只呈现屏幕上可见的内容?的主要内容,如果未能解决你的问题,请参考以下文章

html2canvas截图的清晰度问题

html2canvas 无法正确呈现(重叠颜色)

【解决】html2canvas截图不全的问题

html2canvas截图不全或空白

Vue<解决html2canvas截图不全的问题>

html2canvas 更改 div