如何从Mapbox GL JS

时间:2018-04-12 23:39:08

标签: javascript canvas html5-canvas mapbox mapbox-gl-js

我正在使用Mapbox GL,并尝试获取它的快照,并将快照与覆盖输出的另一个图像合并。

我有一个HTMLCanvasElement关闭屏幕,我首先将从Map.getCanvas()返回的画布写入其中,然后将第二个(Alpha透明)画布写在上面。

问题是,虽然我清楚地看到Map实例中的屏幕上的元素,但结果只显示第二个图像/画布,其余的是空白。

所以我只导出地图的画布,我看到它是因为地图画布是空白的,尽管console.log()显示来自它的图像数据是一大块信息。

这是我的导出功能:

  onExport(annotationCanvas: HTMLCanvasElement) {

    const mergeCanvas: HTMLCanvasElement = document.createElement('canvas');
    const mapCanvas: HTMLCanvasElement = this.host.map.getCanvas();
    const mergeCtx: CanvasRenderingContext2D = mergeCanvas.getContext('2d');

    mergeCanvas.height = annotationCanvas.height;
    mergeCanvas.width = annotationCanvas.width;
    mergeCtx.drawImage(mapCanvas, 0, 0);
    mergeCtx.drawImage(annotationCanvas, 0, 0);

    const mergedDataURL = mergeCanvas.toDataURL();
    const mapDataURL = mapCanvas.toDataURL();
    const annotationDataURL = annotationCanvas.toDataURL();

    console.log(mapDataURL); // Lots of data

    download(mapDataURL, 'map-data-only.png'); // Blank image @ 1920x1080
    download(mergedDataURL, 'annotation.png'); // Only shows annotation (the second layer/canvas) data

  }

这是一个错误,还是我错过了什么?

更新:我想出了这是什么,并有可能的选择。

Mapbox feature request上遇到绊脚石时,我了解到,如果您将Map选项设置为preserveDrawingBuffer(默认设置),则将false实例化,那么您将无法获取具有可用图像数据的画布。但是将此选项设置为true会降低性能。但是,在实例化Map之后,您无法更改此设置...

我希望地图尽可能地发挥最佳效果!!!!

所以,在this answer我偶然发现,对于关于three.js的问题,我了解到如果我在渲染后立即拍摄截图,我将获得所需的画布/数据。

我尝试在捕获画布之前调用this.host.map['_rerender'](),但它仍然返回空白。

然后在源代码中搜索,我找到了一个名为_requestRenderFrame的函数,看起来它可能就是我需要的函数,因为我可以要求Map在下一个渲染周期后立即运行一个函数。但是,由于某种原因,我发现这个函数是omitted in the compiled code, whilst present in the source,显然是因为它只是在主文件中,而不是版本的一部分。

所以我还没有一个满意的解决方案,所以请告诉我任何见解。

1 个答案:

答案 0 :(得分:1)

正如您在更新后的问题中所提到的,解决方案是在地图初始化时设置preserveDrawingBuffer: true

为了回答您更新的问题,我认为@ jfirebaugh在https://github.com/mapbox/mapbox-gl-js/issues/6448#issuecomment-378307311的回答总结得很好:

preserveDrawingBuffer can't be modified on the fly. It has to be set at the time the WebGL context is created, and that can have a negative effect on performance.

It's rumored that you can grab the the canvas data URL immediately after rendering, without needing preserveDrawingBuffer, but I haven't verified that, and I suspect it's not guaranteed by the spec.

因此,尽管可能在渲染后立即抓取画布数据URL,但规格并不能保证。