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

Only renders what's in view #622

Closed
btm1 opened this issue Jun 25, 2015 · 22 comments
Closed

Only renders what's in view #622

btm1 opened this issue Jun 25, 2015 · 22 comments

Comments

@btm1
Copy link

btm1 commented Jun 25, 2015

It would appear the resulting image size is as big as all of the window content including what's overflowed but what's actually visible limited only to the viewport.

This is with me taking overflow off of everything that I could possible take it off of. So there is no css interfering with this. Is it possible to get a content that is outside of the viewport included in the image? I've noticed that even if i scroll the page down and then try it again the result won't even pick up what's in the scrolled viewport but instead still contains what's in the viewport at scrollheight 0.

campaignperformance 30

@btm1
Copy link
Author

btm1 commented Jun 25, 2015

Somehow on your examples on the homepage it shows everything in the body even what's not in view... how did you do that?

@brcontainer
Copy link
Contributor

Possible duplicate from: #117

@justein
Copy link

justein commented Jul 5, 2015

So ,I want to know how can capture an specifed element? do anyone has solution?

@brcontainer
Copy link
Contributor

@justein Try this

<div id="test-case">Test-me</div>
html2canvas(document.getElementById("test-case")).then(function(canvas) {
    document.body.appendChild(canvas);
});

@cchubb
Copy link

cchubb commented Jul 6, 2015

I can confirm this behavior with the latest version. It will render the correct size of the object asked for, but will not actually render to the canvas anything that is off-screen of the current viewport. So if the

<div id="test-case">Test-me</div>

is currently visible in the browser, it will render. If it's off-screen, the canvas is blank (but the right size). Partially visible: Partially rendered. Mine doesn't act like scrollHeight = 0, it renders whatever is visible when the code is executed. (My button is at the bottom).

Like btm's comment, I would like to know how it's done on the example site. Could it be relying on something in Angular or Bootstrap to get the off screen resources?

@brcontainer
Copy link
Contributor

@cchubb I do not understand what Angle and Bootstrap has to do with this. The problem of John, seems to me a matter of rendering a specific element.

If you want render which is outside the view-port, just use

html2canvas(document.body).then(function (canvas) {});

If you want to render elements "overflow" remove the "overflow" at runtime and add again after the process using javascript for add className, like this:

.no-scroll {
     overflow: visible !important;
}

#main {
     overflow: auto;
     height: 200px;
}

<div id="main">
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
</div>

document.getElementById("main").className = "no-scroll";
html2canvas(document.body).then(function (canvas) {
      document.getElementById("main").className = "";
});

Or just point the html2canvas to render the element within the element with "overflow", like this:

#parent {
     overflow: auto;
     height: 200px;
}

#child {
background-color: #fc0;
height: 600px;
}
<div id="parent">
<div id="main">
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
</div>
</div>

html2canvas(document.getElementById("main")).then(function (canvas) {});

Really has many suggestions for features that are unnecessary from my point of view, simply target the correct DOM elements and use the "CSS" to their favor.

@cchubb
Copy link

cchubb commented Jul 8, 2015

I figured it out. You fixed it in 0.5.0-alpha2. If I use the 0.5.0-alpha1 version it clips, but the alpha2 version does not. I didn't even notice that alpha2 was available because the releases page was focusing on alpha1.

Here is a fiddle that demonstrates it working now with alpha2. https://jsfiddle.net/cchubb/fy7tw7ek/1/ if you change the external resource back to alpha1, it will clip when the bottom link is clicked. (You need to save the download file as .png to view it, fiddles won't let me change the output window href to data.)

@btm1, try upgrading to Alpha2.

@btm1
Copy link
Author

btm1 commented Jul 9, 2015

@cchubb I'll give this a shot.

@btm1
Copy link
Author

btm1 commented Jul 9, 2015

@cchubb the underlying issue is fixed in alpha 2 and you're right it's well hidden I didn't even notice there was an alpha 2.

@NPC
Copy link

NPC commented Aug 18, 2015

Hmm, for me even in alpha2 still only the part of the element which is "visible" in the viewport is rendereded. See http://jsfiddle.net/NPC42/ykvL6a17/ for a demonstration—html2canvas exports only those rows that are scrolled into viewport (regardless of whether they are visible in scrolled container div or not).

Am I calling html2canvas wrong somehow? When I test it on my actual code (not the JSFiddle one, which I created just for the demo), this suggestion helps render the whole element: #650, but I hope to avoid hacking the library.

@btm1
Copy link
Author

btm1 commented Aug 24, 2015

@NPC It won't just render what's not in view without you doing anything you have to change it to overflow visible --->export really quickly ---> then change it back to scroll again or it won't work. Not ideal IMO i think there should be an option to just have it work but at least it does.

@NPC
Copy link

NPC commented Aug 24, 2015

@btm1, yes, I assume that's not the intention, since I pass in the element that is within the scrolled one, the element itself doesn't have any overflow trimming.

For now in my app I found that I need to reattach my whole element to body, forcing specific width/height on it (since is contains absolutely positioned elements), in the meantime covering all this kitchen by a full-screen "Preparing export, please wait" overlay, because html2canvas takes 10+ seconds to render it all. After render is done—I attach it back to original location (inside a scrolled container), unsetting width/height.

Cumbersome, but it works.

@bianjp
Copy link

bianjp commented Jan 29, 2016

Strangely, it only renders from the currently visible top boundary of the given element.

Try https://jsfiddle.net/bianjp/bpc3nq69/1/. Scroll to "Print Screen" and click it. The generated image won't include top lines that are not visible when clicked.
Using version 0.5.0.beta4.

Solution is to call $('html, body').scrollTop(0) (or any other way to make the top of the element to render visible) before calling html2canvas.

@simogeo
Copy link

simogeo commented Feb 28, 2017

thanks @bianjp for proposed fix.

Strangely, it only renders from the currently visible top boundary of the given element.

Is that a normal behavior ... It appears very strange to me !

@Brieg
Copy link

Brieg commented Mar 27, 2017

+1

@maiasmith
Copy link

This S.O. answer worked for me.

@ziyoung
Copy link

ziyoung commented Nov 20, 2017

Before calling html2canvas, scroll the element you want to render into viewport.

const el = document.querySelector('#test')
el.scrollIntoView()
setTimeout(function () {
  html2canvas(el, {
    onrendered: function (canvas) {
      document.body.appendChild(canvas)
    },
    useCORS: true
  })
}, 10)

It works for me.
Using version is 0.5.0-beta4.

@niklasvh
Copy link
Owner

Is this still an issue with v1.0.0? If so, could you please share an example on jsfiddle.

@no-response
Copy link

no-response bot commented Dec 12, 2017

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

@Maulik009
Copy link

Maulik009 commented Jun 11, 2018

Hey, @niklashvh

I was also facing the issue for taking snapshot only visible to the DOM. I have version 0.5.0-beta4
So, I am agree with @ziyoung solution. I did the same like he suggest.

           `$('html,body').scrollTop(0);
	 
	 html2canvas( $("#rectangular_div"), {
		 useCORS: true,
		 dpi: 200,
		 
		  onrendered:function(canvas) {
			
			  var str = canvas.toDataURL("image/png");
			  var contentType = 'image/png';
			  console.log(str);
			  b64Data =str;
			  imgFrameSave();
		  }
		})`

So, I set the div position at top 0 to the body and then call html2canvas . So as per my experience, I recommended to use version 0.5.0-beta4 by @eKoopmans so that you can avoid the image pix-elation issue as well as capturing full image from DOM.

@Tholem98
Copy link

Tholem98 commented Feb 4, 2020

That work on desktop but it doesn't work on mobile

@scionGhb
Copy link

scionGhb commented Nov 17, 2020

What I did is window.scrolTo(0,0) before call htmltocanvas(), if you are on top of screen the div is printed complete

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