-
Notifications
You must be signed in to change notification settings - Fork 75
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
Add a map.screenshot() function. #665
Conversation
This returns either a data url or an HTMLCanvasElement. You do not need to preserve drawing buffers for this to work -- that doesn't alway work in Chrome in any case, so WebGL layers are rerendered as part of the screenshot process. This needs testing.
@aashish24 This provides as screenshot of all canvas layers (or a subset of canvas layers). It doesn't require preserveDrawingBuffer to be set ahead of time. I still need to add tests and remove the functionally duplicated code in the testing utilities. If we want to get non-canvas layers, it looks like there is a javascript library that can render html to canvas to some degree that we can look into. |
Codecov Report@@ Coverage Diff @@
## master #665 +/- ##
==========================================
+ Coverage 90.59% 90.62% +0.02%
==========================================
Files 84 84
Lines 8578 8615 +37
==========================================
+ Hits 7771 7807 +36
- Misses 807 808 +1
Continue to review full report at Codecov.
|
Attach a data element to the map's node so that the map is reachable. If a second map is attached to the same node, the first map is destroyed via map.exit(). Improve robustness of testing the blog-lines example. Make sure foreign libraries have a chance to load.
Cool! I will have my first pass on it today.
that would be desirable but I am okay with if that is done in another PR. |
src/map.js
Outdated
* @returns {string|HTMLCanvasElement}: data URL with the result or the | ||
* HTMLCanvasElement with the result. | ||
*/ | ||
this.screenshot = function (layers, type, encoderOptions) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the API
src/map.js
Outdated
result.height = m_height; | ||
var context = result.getContext('2d'); | ||
// start with a white background | ||
context.fillStyle = 'white'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@manthey do we not need to set the transparency? I believe the later drawImage call will update the final value to the combined value of all opacities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The drawImage properly uses the opacity of individual pixels in the canvas, so layers composite properly. But... I did forget that we adjust the opacity of the containing div of the layer when you set the layer opacity, so I'll need to take that into account.
src/map.js
Outdated
// with a library such as rasterizehtml (avialable on npm). | ||
layers.forEach(function (layer) { | ||
$('canvas', layer.node()).each(function () { | ||
if (layer.renderer().api() === 'vgl') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to have it not check for vgl but I understand why we have to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I original thought that if we preserved the drawing buffers, this wouldn't be necessary, but they aren't preserved when the browser tab is switched in any case, so this ends up being necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great.. Just has some minor notes.
Awesome. I was wondering about that. |
One another think I can think of is a GeoJS logo or something of that sort (it could be also used for other PR purposes as well) in the future. What you think? I haven't tried running the branch locally but the changes looks reasonable to me now. |
Also a widget might be useful for screencapture (along with widget to change the basemap). |
You mean watermarking it? As a consumer of open source software, leaving a watermark of your brand on my images is what would make me not use the software anymore. |
It seems like adding a widget could be handled in a separate PR? |
Adding a logo on top of stuff is tricky, as it has to be small to not obscure anything but large enough to be visible, and it has to work on a variety of background. I'd rather see that done as a optional map widget, and then we'd just get that as part of the screenshot if was deliberately present. It should definitely be opt-in, not opt-out. |
yes, all of these features @manthey and I are discussing is for another PR (and to add to the list of issues).
|
@danlamanna wartermaking is not necessarily of geojs logo but for a particular project or company logo. This is something used by the PR folks mostly for presentations or for branding purposes. We can have it off by default. |
@danlamanna please see here: http://leafletjs.com/examples/extending/watermark.html |
Whatever, as long as we don't force it upon the user or leave it as the default or anything like that. #stillOpposed |
+1, totally agree. |
We should create issues for any additional features. I'll ask one more question, though: since you can't copy an image to the clipboard via javascript, what would a screenshot widget do? Does it copy an image to a div so the user can then copy the image to the clipboard themselves? Does it copy the image as a base64-encoded string to the clipboard? Something else? |
@manthey I was hoping (not sure if possible in pure JS environment as I haven't looked) but plottly does have this UI for downloading the plot as png. https://plot.ly/~ElPolloFrio/1911 |
This returns either a data url or an HTMLCanvasElement.
You do not need to preserve drawing buffers for this to work -- that doesn't alway work in Chrome in any case, so WebGL layers are rerendered as part of the screenshot process.
This needs testing.