html2canvas离屏渲染

23

在使用html2canvas时,我有一组DOM对象(相对定位的div包含各种元素),我希望为每个对象创建单独的缩略图。因此,如果有十个div,则会创建十个缩略图。

其中一些对象将超出屏幕 - 每个div都在一个名为“mainDiv”的包含div中。我遍历mainDiv中的div,并逐个执行html2canvas。

对于那些在屏幕上的对象,这很好用。而对于超出屏幕的对象,则会生成空白的缩略图。我创建了一个解决方法,将这些对象滚动到mainDiv的顶部,但这是一种不完美的方法并且不美观。

是否可能指定一个不可见的DOM对象?理想情况下,我想能够指定一个包含div,并让html2canvas忽略父容器的可见性,以便我可以截取隐藏的对象,但如果无法实现这一点,我希望能够截取只是滚动屏幕而已的对象。

有任何想法或建议吗?谢谢!

----以下是一些示例代码。基本上,如果你有一个包含多个div的div,请遍历它们。我实际上使用递归方式进行遍历,以便每次只处理一个div,回调函数调用递归函数,因此看起来像这样:

  function recurser(anIndex, callback) {
    if (anIndex == -1) {
        callback();
        return;
    }
    $(myDivs[anIndex]).html2canvas({
        onrendered : function(canvas) {
            var img = canvas.toDataURL();
            // store the image in an array, do stuff with it, etc.
            recurser(--anIndex, callback);

        }
    })

}

递归调用完成后,它会执行回调函数。回调函数是一个将对图像进行操作的函数。

只要对象在包含#mainDiv中所有div的滚动div内可见,所有这些都能正常工作。但是一旦任何部分的div被滚动出去,它们就会变成黑色。实际上,如果两个div的一半都被卷走了(一个的顶部一半,下一个的底部一半),它们都会完全变成黑色。


请附上一些代码示例。 - anataliocs
@sneuf 这是针对特定浏览器的问题还是在所有浏览器中都有这种行为? - pseudosavant
5个回答

29

我知道这是一个旧问题,但它似乎很有趣。根据我的测试,似乎只有在视口外的 position: absoluteposition: fixed 元素才会导致此问题。我找到了解决方法。

我的做法是制作元素的克隆。将克隆的样式设置为 left = 0top = window.innerHeight(这样它就不会在窗口内),以及 position='relative'。然后将克隆附加到 body 上,在克隆上使用 html2canvas,最后从 body 中删除克隆。这个解决方案适用于 IE、Firefox 和 Chrome。

我已经创建了一个 JSBin 示例。以下是关键的 JavaScript 代码:

function hiddenClone(element){
  // Create clone of element
  var clone = element.cloneNode(true);

  // Position element relatively within the 
  // body but still out of the viewport
  var style = clone.style;
  style.position = 'relative';
  style.top = window.innerHeight + 'px';
  style.left = 0;

  // Append clone to body and return the clone
  document.body.appendChild(clone);
  return clone;
}

var offScreen = document.querySelector('.off-screen');

// Clone off-screen element
var clone = hiddenClone(offScreen);

// Use clone with htm2canvas and delete clone
html2canvas(clone, {
    onrendered: function(canvas) {
      document.body.appendChild(canvas);
      document.body.removeChild(clone);
    }
});

感谢 pseudosavant!! - ddanone
2
这里不起作用:由于某种原因,div 中的并非所有内容都被正确克隆。 - cmbarbu
1
@cmbarbu,您能提供更多细节吗?您使用的是哪个浏览器?您能否设置一个jsbin以重现此问题? - pseudosavant
“hidden”克隆正在附加到<body>。这可能会导致元素与CSS中的某些选择器不匹配。尝试更改代码,使clone元素从clone.parentNode附加/删除。 - pseudosavant
虽然这可能会使克隆的元素离屏幕而出。您可能需要微调CSS选择器,以便元素仍然匹配。 - pseudosavant
显示剩余3条评论

4

将所有父元素的'overflow'属性设置为可见。渲染完成后再将其删除。

CSS

.overflowVisible{
    overflow:visible !important;
}

JS

$("#container").parents().each(function(ind,elem){
    $(elem).addClass("overflowVisible");
});

html2canvas($("#container"), {
    onrendered: function(canvas) {
        var img =canvas.toDataURL("image/png");
        $('body').append(img);
        $("#container").parents().each(function(ind,elem){
            $(elem).removeClass("overflowVisible");
        });
    }
});

2

您可以使用最新版本的html2canvas。这解决了所有图像像素化问题和渲染对象问题。我使用了Erik koopmans的0.5.0-beta4版本参考此处,并按照以下方式调用html2canvas:

$('html,body').scrollTop(0); // Take your <div> / html at top position before calling html2canvas

     html2canvas( $("#my_div"), {
         useCORS: true,
         dpi: 200,

          onrendered:function(canvas) {

              var str = canvas.toDataURL("image/png");
              var contentType = 'image/png';
              console.log(str);
              b64Data =str;
              $('#uploadedImage').val(b64Data); // set image captured by html2canvas
              imgFrameSave(); // Call a function to save your image at server side.
          }
        })

0

0

嗯,你尝试过使用Div display: none; 和 Div display: absolute;(或者你想要的div显示方式 - 也许是z-index)吗?

    arrow1.onclick = (event){
arrow1.style.display = none;
arrow2.style.display = absolute;
}

    arrow2.onclick = (event){
arrow2.style.display = none;
arrow1.style.display = absolute;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接