Question: Google's "Report a Bug" or "Feedback Tool" lets you select an area of your browser window to create a screenshot that is submitted with your feedback about a bug.

![Google Feedback Tool Screenshot](https://i.stack.imgur.com/CDhEi.png)
*Screenshot by Jason Small, posted in a [duplicate question](https://stackoverflow.com/questions/6608327/google-style-send-feedback).* 

How are they doing this? Google's JavaScript feedback API is loaded from [here](https://ssl.gstatic.com/feedback/api.js) and [their overview of the feedback module](http://www.google.com/tools/feedback/intl/en/learnmore.html) will demonstrate the screenshot capability.

Answer: 
JavaScript can read the DOM and render a fairly accurate representation of that using `canvas`. I have been working on a script which converts HTML into a canvas image. Decided today to make an implementation of it into sending feedbacks like you described.

The script allows you to create feedback forms which include a screenshot, created on the client's browser, along with the form. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.

It **does not require any rendering from the server**, as the whole image is created on the client's browser. The HTML2Canvas script itself is still in a very experimental state, as it does not parse nearly as much of the CSS3 attributes I would want it to, nor does it have any support to load CORS images even if a proxy was available.

Still quite limited browser compatibility (not because more couldn't be supported, just haven't had time to make it more cross browser supported).

For more information, have a look at the examples here:

<http://hertzen.com/experiments/jsfeedback/>

**edit**
The html2canvas script is now available separately [here](https://github.com/niklasvh/html2canvas) and some [examples here](http://html2canvas.hertzen.com/).

**edit 2**
Another confirmation that Google uses a very similar method (in fact, based on the documentation, the only major difference is their async method of traversing/drawing) can be found in this presentation by Elliott Sprehn from the Google Feedback team:
<http://www.elliottsprehn.com/preso/fluentconf/>
Here is a complete screenshot example that works with chrome in 2021. The end result is a blob ready to be transmitted. Flow is: request media > grab frame > draw to canvas > transfer to blob. If you want to do it more memory efficient explore [OffscreenCanvas](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas) or possibly [ImageBitmapRenderingContext](https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmapRenderingContext)

<https://jsfiddle.net/v24hyd3q/1/>

```
// Request media
navigator.mediaDevices.getDisplayMedia().then(stream => 
{
  // Grab frame from stream
  let track = stream.getVideoTracks()[0];
  let capture = new ImageCapture(track);
  capture.grabFrame().then(bitmap => 
  {
    // Stop sharing
    track.stop();

    // Draw the bitmap to canvas
    canvas.width = bitmap.width;
    canvas.height = bitmap.height;
    canvas.getContext('2d').drawImage(bitmap, 0, 0);

    // Grab blob from canvas
    canvas.toBlob(blob => {
        // Do things with blob here
        console.log('output blob:', blob);
    });
  });
})
.catch(e => console.log(e));

```