html2canvas 捕获除内部 canvas 内容以外的所有内容

html2canvas captures everything except the content of an inner canvas

我有一张用 leaflet 渲染的地图。

我需要使用 html2canvas.

截取该地图

要使用 html2canvas,我需要提供一个 DOM 元素来捕获 (elementToCapture) 和一个可选配置 (html2canvasConfiguration)。

var html2canvasConfiguration = {
    useCORS: true,
    width: map._size.x,
    height: map._size.y,
    backgroundColor: null,
    logging: true,
    imageTimeout: 0
};

var elementToCapture = map._container.getElementsByClassName('leaflet-pane leaflet-map-pane')[0];
html2canvas(elementToCapture, html2canvasConfiguration).then(function (canvas) {
    var link = document.createElement('a');
    link.download = 'test.png';
    link.href = canvas.toDataURL();
    link.click();
    link.remove();
})

我通过 leaflet-pane leaflet-map-pane class 提取了一个元素,它基本上代表了整个地图,包括控件(缩放 in/out 按钮、比例尺等)、自定义标记、工具提示、叠加层, 弹出窗口。

整个DOM长得像

<div class="leaflet-pane leaflet-map-pane">
    <div class="leaflet-pane leaflet-tile-pane">
        <div class="leaflet-gl-layer mapboxgl-map">
            <div class="mapboxgl-canvas-container">
                <canvas class="mapboxgl-canvas leaflet-image-layer leaflet-zoom-animated"></canvas>
            </div>
            <div class="mapboxgl-control-container"></div>
        </div>
    </div>
    <div class="leaflet-pane leaflet-shadow-pane"></div>
    <div class="leaflet-pane leaflet-overlay-pane"></div>
    <div class="leaflet-pane leaflet-marker-pane"></div>
    <div class="leaflet-pane leaflet-tooltip-pane"></div>
    <div class="leaflet-pane leaflet-popup-pane"></div>
<div class="leaflet-control-container"></div>

我遇到的问题是 leaflet-pane leaflet-tile-pane 元素(尤其是内部 canvas 的内容)没有被 html2canvas 捕获。简单来说,我在地图上看到了所有东西,但我没有看到地图本身

更新 1:

我目前使用的版本是1.0.0-rc.1(最新的)

更新 2:

canvas的性质是webgl。这可能是问题所在吗?根据 this,他们确实支持 webgl canvases.

更新 3:

我试图以编程方式获取 canvas 并对其调用 toDataURL。即使使用 preserveDrawingBuffer 黑客攻击,它也会生成一个空白的屏幕截图。

更新 4:

奇怪的是,它不只捕获某些 canvases。我创建了一个 2d canvas(通过将 preferCanvas 添加到地图配置)并显示出来。

试试这个,将其添加到页面顶部,在任何其他脚本之前

<script>
HTMLCanvasElement.prototype.getContext = function(origFn) {
  return function(type, attribs) {
    attribs = attribs || {};
    attribs.preserveDrawingBuffer = true;
    return origFn.call(this, type, attribs);
  };
}(HTMLCanvasElement.prototype.getContext);
</script>

有帮助吗?