8

I have a set-up with multiple variables that users can alter that effect a visual representation of an element. All of this is controlled by jquery scripts. It would be cool if there was a way to save the resultant image as per what the browser renders. It'd be no different than a screencapture from a user perspective, though it would only capture the relevant area.

I have a plugin for FF called Page Saver, and it's functionality is pretty much what i am looking for, but with jquery or regular javascript if possible.

I'm more asking for tips, and a general direction that you guys would advise me to go in in order to pursue such functionality. I'd prefer not to learn another language to do this, but if i must...

C_K
  • 1,243
  • 4
  • 18
  • 29

2 Answers2

14

Edit : This method only works in Firefox extensions.

You can use HTML5 canvas, Firefox' drawWindow and the toDataURL method. For example:

var capture = function() {
  var root = document.documentElement;
  var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'html:canvas');
  var context = canvas.getContext('2d');
  var selection = {
    top: 0,
    left: 0,
    width: root.scrollWidth,
    height: root.scrollHeight,
  };

  canvas.height = selection.height;
  canvas.width = selection.width;

  context.drawWindow(
    window,
    selection.left,
    selection.top,
    selection.width,
    selection.height,
    'rgb(255, 255, 255)'
  );

  return canvas.toDataURL('image/png', '');
};

You can adjust top, left, width and height to capture only a part of the web page.

The result is a data URI string. You can send it to your server or draw it on another canvas:

  var canvas = document.getElementById('captured');
  var ctx = canvas.getContext('2d');
  var image = new Image();
  image.src = capture();

  // the image is not immediately usable
  $(image).load(function() { // jquery way
    canvas.width = image.width;
    canvas.height = image.height;
    ctx.drawImage(image, 0, 0);
  });

Your plugin probably uses this method. You can also check its source code.

Edit: To send it to your server with JQuery you can do something like that:

$("#send-capture-button").click(function() {
  $.post("/url-to-send-image-to", {image_data: capture()})
});

On the server side you'll have to decode the data URL.

Michaël Witrant
  • 7,525
  • 40
  • 44
  • Wow, I'll have o play around with this and see if I cant get it to do what I need. Thanks for the very indepth answer! This uses HTML5, so only newer browsers will be able to employ such functionality? – C_K May 10 '11 at 17:20
  • You can check http://caniuse.com/#search=canvas but I don't know if the "canvas basic support" includes this method. – Michaël Witrant May 10 '11 at 17:50
  • It took me a while before i was ready to implement this script. I'm not sure how to implement it though, how do i trigger the image creation, and where would the resultant image show up? – C_K May 18 '11 at 16:35
  • could you clarify what html structure i'd need for this? – C_K May 20 '11 at 03:09
  • You don't need any HTML structure (except if you want to use the sample that draws the image on the document, then you'd need a `` somewhere on the page). I added a sample to send the image to your server. – Michaël Witrant May 29 '11 at 11:57
  • this does not work: Uncaught TypeError: Object # has no method 'drawWindow' look:http://jsbin.com/oribiy/1/edit –  Sep 03 '12 at 12:04
  • You're right. [It only works in Firefox extensions](https://developer.mozilla.org/en-US/docs/DOM/CanvasRenderingContext2D#drawWindow()). I edited the answer. – Michaël Witrant Sep 03 '12 at 18:53
  • does it have to be canvas or does it also work for any HTML element? – Moe Sweet Jul 16 '13 at 08:15
0

There is no JS functionality built into browsers that would allow you turn an image into HTML sadly. So you would need something like a browser plugin or extension installed that has a JS API that you can call into. But even then, it would obviously require that plugin be installed on that persons browser.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337