Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

html2canvas offscreen

In using html2canvas, I have a stack of DOM objects (relative positioned div's that contain various things), that I wish to create individual thumbnails for. So if there are ten divs, I will create ten thumbnails.

Some of these objects will be offscreen --each of these divs are in a single, encompassing div called "mainDiv". I iterate through the divs within mainDiv and execute the html2canvas on each of them individually.

For those that are onscreen, this works fine. Those that are offscreen do not -- they come back blank. I created a workaround that scrolls the objects to the top of the mainDiv, however this is a kludge and visually unappealing.

Is it possible to specify a DOM object that is not visible? Ideally, I'd like to be able to specify a containing div and have html2canvas ignore the parent visibility, so I can screen capture hidden objects, but barring that, I'd like to be able to screen capture objects that are simply scrolled off screen.

Any thoughts, ideas? Thanks!

---- Here is some example code. Basically, if you had a bunch of divs within a div, iterate through them. I actually do this recursively so that only one gets processed at a time, with the callback calling the recursive function, so it looks something like this:

  function recurser(anIndex, callback) {
    if (anIndex == -1) {
        callback();
        return;
    }
    $(myDivs[anIndex]).html2canvas({
        onrendered : function(canvas) {
            var img = canvas.toDataURL();
            // store the image in an array, do stuff with it, etc.
            recurser(--anIndex, callback);

        }
    })

}

Once the recursive calls are complete, it executes the callback function, which is a function that will do stuff with the images.

Again, all this works fine as long as the objects are visible within the scrolling div that contains all of the divs in #mainDiv. Once any part of the divs are scrolled off, however, they render black. In fact, if half of two divs are scrolled off (the top half of one, the bottom half of the next), they both render completely black.

like image 679
sneuf Avatar asked Nov 27 '12 19:11

sneuf


3 Answers

I know this is an old question but it seemed kind of interesting. Based on my testing it seemed like only position: absolute and position:fixed elements that were outside of the viewport caused this issue. I figured out a solution to the problem.

What I'm doing is making a clone of the element. Setting the styling of the clone to left = 0, top = window.innerHeight (so that it won't be inside the window) and position = 'relative'. Then I append the clone to the body, use html2canvas on the clone, and then remove the clone from the body. This solution works for me in IE, Firefox, and Chrome.

I have created a JSBin example here. Here is the key javascript code:

function hiddenClone(element){
  // Create clone of element
  var clone = element.cloneNode(true);

  // Position element relatively within the 
  // body but still out of the viewport
  var style = clone.style;
  style.position = 'relative';
  style.top = window.innerHeight + 'px';
  style.left = 0;

  // Append clone to body and return the clone
  document.body.appendChild(clone);
  return clone;
}

var offScreen = document.querySelector('.off-screen');

// Clone off-screen element
var clone = hiddenClone(offScreen);

// Use clone with htm2canvas and delete clone
html2canvas(clone, {
    onrendered: function(canvas) {
      document.body.appendChild(canvas);
      document.body.removeChild(clone);
    }
});
like image 144
pseudosavant Avatar answered Nov 02 '22 03:11

pseudosavant


set 'overflow' as visible for all of its parent elements. After rendered remove it

CSS

.overflowVisible{
    overflow:visible !important;
}

JS

$("#container").parents().each(function(ind,elem){
    $(elem).addClass("overflowVisible");
});

html2canvas($("#container"), {
    onrendered: function(canvas) {
        var img =canvas.toDataURL("image/png");
        $('body').append(img);
        $("#container").parents().each(function(ind,elem){
            $(elem).removeClass("overflowVisible");
        });
    }
});
like image 35
Anbu Avatar answered Nov 02 '22 05:11

Anbu


You can use the latest version of html2canvas. This resolves all images pix-elation issues and rendering object issue. I used the version 0.5.0-beta4 by Erik koopmans refer this and called the html2canvas as below:

$('html,body').scrollTop(0); // Take your <div> / html at top position before calling html2canvas

     html2canvas( $("#my_div"), {
         useCORS: true,
         dpi: 200,

          onrendered:function(canvas) {

              var str = canvas.toDataURL("image/png");
              var contentType = 'image/png';
              console.log(str);
              b64Data =str;
              $('#uploadedImage').val(b64Data); // set image captured by html2canvas
              imgFrameSave(); // Call a function to save your image at server side.
          }
        })
like image 2
Maulik Avatar answered Nov 02 '22 03:11

Maulik