Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Request] Screenshot capture with preserveDrawingBuffer: false #2766

Closed
kristfal opened this issue Jun 20, 2016 · 4 comments
Closed

[Request] Screenshot capture with preserveDrawingBuffer: false #2766

kristfal opened this issue Jun 20, 2016 · 4 comments

Comments

@kristfal
Copy link

Hey,

it is currently possible to grab screenshots of the map to a dataURI while preserveDrawingBuffer is set to true. As noted in the documentation, this comes at a performance cost – and it is very noticeable on mobile devices (A Galaxy S3 drops to roughly 50% of regular FPS with this flag enabled).

It is apparently possible to grab screenshots of WebGL canvases without preserving the drawing buffer. See this stackoverflow:

http://stackoverflow.com/questions/30628064/how-to-toggle-preservedrawingbuffer-in-three-js

Would be great is mapbox-gl-js followed this implementation to get around the performance overhead of preserveDrawingBuffer.

@jfirebaugh
Copy link
Contributor

The answer to the SO post asserts that it's possible to get the drawing buffer without preserveDrawingBuffer: true so long as you do so immediately after rendering. If that's true, then there's nothing special mapbox-gl-js needs to do: you can attach an event listener to the map render event and obtain the buffer at that point.

@fxi
Copy link

fxi commented Mar 6, 2018

Here is a way of grabbing a screenshot when preserveDrawingBuffer is false :

function takeScreenshot(map) {
  return new Promise(function(resolve, reject) {
    map.once("render", function() {
      resolve(map.getCanvas().toDataURL());
    });
    /* trigger render */
    map.setBearing(map.getBearing());
  })
}
/* example */
takeScreenshot(map).then(function(data){
  console.log(data);
})

@ofek-a
Copy link

ofek-a commented Mar 19, 2020

@fxi Thanks for the great solution.

I had to trigger the render a bit differently, by using map._render(); instead of map.setBearing(map.getBearing());

I used a different method because map.setBearing(map.getBearing()); was triggering a moveend event which in my use-case is what triggers the takeScreenshot function and subsequently the render in the first place, leading to a never-ending cycle of moveend -> render -> moveend etc etc..

I'm not sure if that's the best way to do it, so if anyone has a better way of triggering the render please let me know 😊

manuelkasper pushed a commit to manuelkasper/sotlas-frontend that referenced this issue Jun 18, 2021
@fxhinze
Copy link

fxhinze commented Sep 15, 2022

@ofeka I used the map.triggerRepaint() method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants