javascript - 如何从 Mapbox GL JS 获取可用的 Canvas

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

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

我在屏幕外有一个 HTMLCanvasElement,我首先将 Map.getCanvas() 返回的 Canvas 写入它,然后写入第二个(alpha 透明) Canvas 。

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

所以我只导出 map 的 Canvas ,我看到这是因为 map Canvas 是空白的,尽管 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 ,我了解到,如果您将 preserveDrawingBuffer 选项设置为 false(默认值)来实例化您的 Map,您将无法获得 Canvas 与可用的图像数据。但是将此选项设置为 true 会降低性能。但是在 Map 实例化后你不能改变这个设置...

我希望 Map 尽可能地发挥最佳性能!!!!

所以,在 this answer 上我无意中发现,关于一个关于 three.js 的问题,我了解到如果我在渲染后立即截屏,我将获得我需要的 Canvas /数据。

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

然后在源代码中四处搜索,我发现了一个名为 _requestRenderFrame 的函数,看起来它可能是我需要的,因为我可以要求 Map 在下一次渲染后立即运行一个函数循环。但由于某种原因,我发现该函数是 omitted in the compiled code, whilst present in the source ,显然是因为它只在母版中,而不是发行版的一部分。

所以我还没有真正令人满意的解决方案,所以请让我知道任何见解。

最佳答案

正如您在更新的问题中提到的,解决方案是在 map 初始化时设置 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.

因此,尽管可能会在渲染后立即获取 Canvas 数据 URL,但规范并不能保证这一点。

关于javascript - 如何从 Mapbox GL JS 获取可用的 Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49807311/

相关文章:

php - 单选输入在页面重新加载时消失(枚举、foreach、默认选中、记住页面重新加载时的答案)

html - 在 Canvas 中反向剪裁

javascript - 使用 JavaScript 和 Canvas 在单轴上扭曲图像

android - 从 Canvas 上删除,最后一个 canvas.drawPath()

jquery - 修改 jQuery UI 颜色选择器 slider 以包含黑色和白色值

javascript - KonvaJS:如何用箭头连接两个形状?

javascript - 从Url中获取特定字符串

javascript - 谷歌图表中的预选点

javascript - 在 PHP 中使用源映射对 JavaScript 进行反混淆

javascript - Uncaught ReferenceError : ctx is not defined