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

Snapshot for Mapbox GL JS #6448

Closed
samsammurphy opened this issue Apr 3, 2018 · 15 comments
Closed

Snapshot for Mapbox GL JS #6448

samsammurphy opened this issue Apr 3, 2018 · 15 comments
Assignees

Comments

@samsammurphy
Copy link

samsammurphy commented Apr 3, 2018

Motivation

Create a png/jpeg image of a map and all its visible layers using GL JS, similar too:

My aim is to allow users to find awesome content on a map and readily share it using social media posts that we help generate for them, with an image of what they were looking at.

Design Alternatives

The current working solution is a bit clunky and hard to find online. In summary, set preserveDrawingBuffer = true when initializing the map, then use map.getCanvas().toDataURL() to get a base64 encoded image.

Design

Mock-Up

.. I love sugar.. I would suggest having a method for developers called map.snapShot()

Concepts

Then I would make it easy to find by adding it to the examples.

Implementation

map.snapShot() would effectively

set preserveDrawingBuffer to true (if not already)
get image using map.getCanvas().toDataURL()
set preserveDrawingBuffer back to false (if that's what it was before the call).

return the image
@jfirebaugh
Copy link
Contributor

I'm not sure this is possible to encapsulate.

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.

@samsammurphy
Copy link
Author

My suggestion would then be to add an official example. Is it ok to suggest that here?

It might look something like this.

@mollymerp
Copy link
Contributor

@samsammurphy if you want to submit a PR with an example of how to do this, we'd gladly review it! One thing to be sure of is that the OSM attribution and Mapbox logo need to be included on the static screencaps.

@samsammurphy
Copy link
Author

@mollymerp ok, will try to familiarize myself with contribute examples and batfish and then make a PR.

@mollymerp
Copy link
Contributor

Let me know if you need any help!
Here are the docs for adding examples https://github.com/mapbox/mapbox-gl-js/blob/master/docs/README.md#writing-examples

@BBaysinger
Copy link

I'm stuck on this issue currently: https://stackoverflow.com/questions/49807311/how-to-get-usable-canvas-from-mapbox-gl-js. Any insight would be greatly appreciated.

@samsammurphy
Copy link
Author

Hi @mollymerp,

I put together a single html file that executes a snapshot example: snapshot.html.zip

I could do with some help converting this to a batfish friendly format. I am not familiar with React or Webpack and the bare minimum to get started is a nine point bullet point list (!)

Is the first step at the root dir for the mapbox-gl-js repo?

npm install --save @mapbox/batfish react react-dom react-helmet

If so, the second step will result in a name collision with existing scripts start and build.

// add these to the package.json as new scripts
"start": "batfish start", "build": "batfish build", "serve-static": "batfish serve-static"

Thanks in advance

@andrewharvey
Copy link
Collaborator

andrewharvey commented Apr 15, 2018

@samsammurphy You don't need to know anything about batfish, webpack or react to put together GL JS examples, it might help to take a look at how an existing example is defined at:

https://github.com/mapbox/mapbox-gl-js/blob/master/docs/pages/example/simple-map.js
https://github.com/mapbox/mapbox-gl-js/blob/master/docs/pages/example/simple-map.html

just add your new example like that in a new branch of your fork and it should be added automatically when you yarn run start-docs

I took at look at your example code, it's a great start! I think the preference is to avoid libraries like jQuery to make the examples as portable as possible, would you be able to use plain JS?

As @mollymerp mentioned you'll need to add some code to ensure the LogoControl and AttributionControl are retained:

Here is roughly how I've done that in the past:

  var logo = document.getElement(get the logo element)
  ctx.drawImage(logo, 0 + logoPadding, mapCanvas.getAttribute('height') - logo.height);

As for the attribution, you'll probably need to get the text and draw it on the canvas with https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text

@andrewharvey
Copy link
Collaborator

@samsammurphy PS. It will be easier to comment on the code if you open up a new PR with your changes.

@samsammurphy
Copy link
Author

@andrewharvey I'm (obviously) a newb at this, just opened a PR with a basic outline, still need to implement the logo and attribution transfer.

The example starts with quite a bit of CSS relative to the other examples.

I'm running yarn run start-docs from the repo's root dir and getting an error.

$ cd path-to-repo
$ yarn run start-docs
ERROR: [Errno 2] No such file or directory: 'run'

My understanding is that command is supposed to run a script in the package.json (akin to npm run). What am I doing wrong?

@andrewharvey
Copy link
Collaborator

@andrewharvey I'm (obviously) a newb at this, just opened a PR with a basic outline, still need to implement the logo and attribution transfer.

Looks good so far!

My understanding is that command is supposed to run a script in the package.json (akin to npm run). What am I doing wrong?

That's correct. Did you run through https://github.com/mapbox/mapbox-gl-js/blob/master/CONTRIBUTING.md? In particular did you first run yarn install?.

@samsammurphy
Copy link
Author

ah ha! apt-get had installed the wrong program (!) that explains the weird error messages.

@andrewharvey
Copy link
Collaborator

andrewharvey commented May 25, 2018

@P-Zenker If you add those markers / lines / etc. as part of the style rather than using the GL JS Marker or Canvas then @samsammurphy's snapshot example #6518 and the revised example at #6846 will include them.

@P-Zenker
Copy link

@andrewharvey Yeah, thanks - I figured that out a few seconds after my (deleted) question :)

@katydecorah
Copy link
Contributor

Closing here as this issue has gone stale and the content for the example may be out of scope.

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

No branches or pull requests

9 participants