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

Canvas rendered with a big blank offset if I scroll to the bottom of the captured element #1878

Closed
2 tasks done
woteska opened this issue Jun 10, 2019 · 50 comments · Fixed by #2625
Closed
2 tasks done

Comments

@woteska
Copy link

woteska commented Jun 10, 2019

  • You are using the latest version
  • You are testing using the non-minified version of html2canvas and checked any potential issues reported in the console

Bug reports:

In 1.0.0-rc.3
If I scroll to the top of the page (where the element starts), it works perfectly.
Wrong: https://ibb.co/8Y9SnTV (scrolling to the bottom of the element)
Good: https://ibb.co/7z1903r (scrolling to the top of the element)

      window.scrollTo(0, 0); // <-- this fixes the issue
      html2canvas(document.getElementById('drag-container-outer')).then((canvas) => {
        var a = document.createElement('a');
        a.href = canvas.toDataURL('image/jpeg');
        a.download = 'somefile.jpg';
        a.click();
      });

In 1.0.0-rc.1
Works perfectly, there is no need to scroll.

Specifications:

  • html2canvas version tested with: --- wrong: v1.0.0-rc.3 | good: 1.0.0-rc.1
  • Browser & version: Chrome 75.0.3770.80
  • Operating system: Windows
@1014156094
Copy link

Me too

@TuffyLiu
Copy link

me too

1 similar comment
@song7788q
Copy link

me too

@fangsueluo
Copy link

I also, when I scroll the page, the canvas will be blank, but when I not scroll, the canvas is ok, really want to know why?

@rockPrince
Copy link

As long as the page scrolls, a blank space appears above the screenshot and the longer the scroll, the more blank

@GerkinDev
Copy link

GerkinDev commented Jul 9, 2019

Hey people ! I had the same problem, but I managed to fix it using explicit scrollX & scrollY options, set to 0. See http://html2canvas.hertzen.com/configuration/

Cheers ! 🍻

@1014156094
Copy link

Hey people ! I had the same problem, but I managed to fix it using explicit scrollX & scrollY options, set to 0. See http://html2canvas.hertzen.com/configuration/

Cheers ! 🍻

Thanks!

@GerardoFurtado
Copy link

GerardoFurtado commented Jul 16, 2019

I was facing the same problem, but setting scrollY: 0 didn't fix it. I ended up fixing it by reversing the vertical scroll with window.scrollY, like this:

{
    scrollX: 0,
    scrollY: -window.scrollY
}

As this is quite a hack it would be really great having this issue fixed! Cheers 🍻

@h330894169
Copy link

h330894169 commented Aug 1, 2019

me too. i have dialog, dialog position is fixed; body too height. use 1.0.0-rc.1, in Chrome it's good. in ios.use UIWebView it's bad. generator dialog img is transparent

@jtremoulet
Copy link

Hello,

I'm facing the same problem. I have tried to set scrollY to 0, to (-window.scrollY), to a fixed value.
I have also tried to use 1.0.0-rc.1.

But none of these solutions fixed my problem.

I use HTML2Canvas with Angular, I don't face the problem in dev mode but only in prod mode.

@hakimio
Copy link

hakimio commented Aug 9, 2019

@jtremoulet

I have also tried to use 1.0.0-rc.1.

Maybe, like some of the others here you tried installing it using the caret ("^") version prefix? RC1 doesn't have the issue mentioned in this bug report.

@jtremoulet
Copy link

@jtremoulet

I have also tried to use 1.0.0-rc.1.

Maybe, like some of the others here you tried installing it using the caret ("^") version prefix? RC1 doesn't have the issue mentioned in this bug report.

Thank you, that was my problem

@wlj231210
Copy link

Cheers ! 🍻

@claudio147
Copy link

I was facing the same problem, but setting scrollY: 0 didn't fix it. I ended up fixing it by reversing the vertical scroll with window.scrollY, like this:

{
    scrollX: 0,
    scrollY: -window.scrollY
}

As this is quite a hack it would be really great having this issue fixed! Cheers 🍻

If you want to support IE11 just use scrollY: -window.pageYOffset

@kaluabentes
Copy link

Hey guys, I'm having the same problem in 1.0.0-rc.1, any suggestions?

@kaluabentes
Copy link

I was facing the same problem, but setting scrollY: 0 didn't fix it. I ended up fixing it by reversing the vertical scroll with window.scrollY, like this:

{
    scrollX: 0,
    scrollY: -window.scrollY
}

As this is quite a hack it would be really great having this issue fixed! Cheers

This solution solved my problem

@ghost
Copy link

ghost commented Nov 14, 2019

None of these work for me, are there any other possible solutions?

@tu4mo
Copy link

tu4mo commented Nov 14, 2019

Only thing that worked for me was downgrading to 1.0.0-alpha.12.

@DanLatimer
Copy link

Only thing that worked for me was downgrading to 1.0.0-alpha.12.

I was experiencing a few issues and downgrading to 1.0.0-alpha.12 did the trick for me too, thanks!

@leasontou
Copy link

leasontou commented Nov 23, 2019

Two ways worked for me:

  1. window.scrollTo(0, 0) before you do html2canvas.
  2. downgrading to 1.0.0-alpha.12

@GerkinDev
Copy link

It would be nice to have some e2e testing to avoid this issue to reappear...

@coolguy001tv
Copy link

Only thing that worked for me was downgrading to 1.0.0-alpha.12.

I was experiencing a few issues and downgrading to 1.0.0-alpha.12 did the trick for me too, thanks!

1.0.0-alpha.12 is ok in this issue, but I found it not ok in some other aspects such as font size...

@littlePig-zzf
Copy link

image
The case of using scrollY mentioned in the document is that the box of our generated pictures must be set to position:fixed to take effect.
You can add the following styles to the box:
position: fixed; left: 0; top: 0;
and then,html2Canvas configuration:
{ scrollY: 0 }
Here's how I solved the problem of the generated image being offset by scrolling.

@abogaard
Copy link

I just downgraded on 14/04/2020 to 1.0.0-alpha.12 and it is handling my screenshots of divs much better than the current version. I spent the last day tweaking the scroll and window and x and could never get it to work right on all divs. The downgrade works properly with simply height and width set.

@rushglen
Copy link

rushglen commented Apr 18, 2020

window.scrollTo(0, 0) before you do html2canvas.
worked for me.
you can of course store the y offset and then immediately after html2canvas do:
window.scrollTo(0, scrollamount);

causes a "WTF" moment as the page (from the users perspective) jumps up and down, but this hack works!

@mehmetyagci
Copy link

image
The case of using scrollY mentioned in the document is that the box of our generated pictures must be set to position:fixed to take effect.
You can add the following styles to the box:
position: fixed; left: 0; top: 0;
and then,html2Canvas configuration:
{ scrollY: 0 }
Here's how I solved the problem of the generated image being offset by scrolling.

It's worked. But it is not a good solution.

@malini1993
Copy link

Doing this helped me:

  1. scrollY: -window.pageYOffset
  2. scrollX: 0
  3. downgrading to 1.0.0-alpha.12

@apakbaz
Copy link

apakbaz commented Sep 8, 2020

for me none of the above works on iOS except for window.scrollTo(0, 0) which is a weird experience and definitely looks like a hack! is there anyone here having the same issue with iOS?

{ scrollX: 0, scrollY: -window.scrollY }
this works everywhere except for iOS!

@OliverCodez
Copy link

I was facing the same problem, but setting scrollY: 0 didn't fix it. I ended up fixing it by reversing the vertical scroll with window.scrollY, like this:

{
    scrollX: 0,
    scrollY: -window.scrollY
}

As this is quite a hack it would be really great having this issue fixed! Cheers beers

Same here, was not able to get a proper render with any other settings changes, this was the solution!! Thank You!!

@enkr1
Copy link

enkr1 commented Nov 19, 2020

for me none of the above works on iOS except for window.scrollTo(0, 0) which is a weird experience and definitely looks like a hack! is there anyone here having the same issue with iOS?

{ scrollX: 0, scrollY: -window.scrollY }
this works everywhere except for iOS!

Any latest solution for Safari? Need help

@ahmedfeyzi
Copy link

I solved all possible problems as follows..

html2canvas(element , {
        scrollX: -window.scrollX,
        scrollY: -window.scrollY,
        windowWidth: document.documentElement.offsetWidth,
        windowHeight: document.documentElement.offsetHeight
})

@apakbaz
Copy link

apakbaz commented Dec 9, 2020

I solved all possible problems as follows..

html2canvas(element , {
        scrollX: -window.scrollX,
        scrollY: -window.scrollY,
        windowWidth: document.documentElement.offsetWidth,
        windowHeight: document.documentElement.offsetHeight
})

Thanks but it did not fix the issue with iOS unfortunately, still you have to scroll to the top of the page, capture the screen and then scroll back!

@enkr1
Copy link

enkr1 commented Dec 17, 2020

I solved all possible problems as follows..

html2canvas(element , {
        scrollX: -window.scrollX,
        scrollY: -window.scrollY,
        windowWidth: document.documentElement.offsetWidth,
        windowHeight: document.documentElement.offsetHeight
})

Thanks but it did not fix the issue with iOS unfortunately, still you have to scroll to the top of the page, capture the screen and then scroll back!

In my case, it happens in a pop-up modal on the Safari browser.

The full div can be rendered (in the modal) on Chrome and Firefox. On Safari, when u scroll down of the modal, the bottom part of the captured element will be cut off.

@DevinXian
Copy link

DevinXian commented Jan 8, 2021

  1. downgrading to 1.0.0-alpha.12
  2. custom onclone option as below:
const rect = document.querySelector('#render-me').getBoundingClientRect();
const options = {
    onclone: (doc) => {
      const ele = doc.querySelector('#render-me');
      ele.style.position = 'fixed';
      ele.style.left = 0;
      ele.style.right = 0;
      ele.style.top = `${rect.y}px`;
   },
}

#render-me is the html fragment to be rendered.

@yungo1846
Copy link

yungo1846 commented Jan 19, 2021

function setTimer(callback) {
  setTimeout(function () {
    window.scrollTo(0, 0); // this is working!
    console.log("first");
    callback();
  }, 500);
}

setTimer(function () {
  html2canvas(document.getElementById("some_id")).then((canvas) => {
    saveAs(canvas.toDataURL("image/png", 1), "image_name.png");
    console.log("second");
  });
});

function saveAs(uri, filename) {
  let link = document.createElement("a");
  if (typeof link.download === "string") {
    link.href = uri;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  } else {
    window.open(uri);
  }
}

In my case, I tried everything above, but it didn't work well on mobile and iOS. So instead of adding scroll options, I chose the way to force the screen up using scrollTo. The setTimer function and callback function allow screen to be raised first and captured later synchronously. You can easily check the order of code execution through console.log.

With this method, I checked that image capture works well as desired in mobile and iOS environments.

@crb596
Copy link

crb596 commented Feb 24, 2021

Any updates on this? The closest I have got to a fix is the window.scrollTo(0, 0) which works nearly everywhere except for mobile when the address bar is expanded. For example, if you scroll down the address bar collapses and calling window.scrollTo(0, 0) sets to the top as I'd hope and no clipping. When the page first loads and the address bar is open I get a white gap along the bottom of the render however.

@danielholmes
Copy link

danielholmes commented Feb 26, 2021

I've found this solution to work well:

#1981 (comment)

html2canvas(element , {
        scrollX: -window.scrollX,
        scrollY: -window.scrollY,
        windowWidth: document.documentElement.offsetWidth,
        windowHeight: document.documentElement.offsetHeight
})

@crb596
Copy link

crb596 commented Feb 26, 2021

I've found this solution to work well:

#1981 (comment)

html2canvas(element , {
        scrollX: -window.scrollX,
        scrollY: -window.scrollY,
        windowWidth: document.documentElement.offsetWidth,
        windowHeight: document.documentElement.offsetHeight
})

I found that scrollX/Y was unresponsive unless the element was position fixed as mentioned in the references.

I found a solution but I am not happy with how round about it is

        target.style.position = "fixed";
  	target.style.left = "0";
  	target.style.top = "0";
	window.scroll(0,0);

 	html2canvas($('#target')[0], {
    	        scrollY: 0,
    	        scrollX: 0,
    	       backgroundColor: "rgba(0,0,0,0)",
  	}).then(canvas => {
    	        var a = document.createElement('a');
      	        a.href = canvas.toDataURL('png');
      	        a.download = 'myfile.png';
      	        a.click();
    
    	       //Clean up everything after image is done being made
   		artDivDOM.style.position = "absolute";
  		artDivDOM.style.left = tempLeft;
  		artDivDOM.style.top = tempTop;
  })`

@fmoya-laboral
Copy link

I was facing the same problem, but setting scrollY: 0 didn't fix it. I ended up fixing it by reversing the vertical scroll with window.scrollY, like this:

{
    scrollX: 0,
    scrollY: -window.scrollY
}

As this is quite a hack it would be really great having this issue fixed! Cheers 🍻

Wow! Thank you very much, you saved my life <3

@JunyWuuuu91
Copy link

I've found this solution to work well:
#1981 (comment)

html2canvas(element , {
        scrollX: -window.scrollX,
        scrollY: -window.scrollY,
        windowWidth: document.documentElement.offsetWidth,
        windowHeight: document.documentElement.offsetHeight
})

I found that scrollX/Y was unresponsive unless the element was position fixed as mentioned in the references.

I found a solution but I am not happy with how round about it is

        target.style.position = "fixed";
  	target.style.left = "0";
  	target.style.top = "0";
	window.scroll(0,0);

 	html2canvas($('#target')[0], {
    	        scrollY: 0,
    	        scrollX: 0,
    	       backgroundColor: "rgba(0,0,0,0)",
  	}).then(canvas => {
    	        var a = document.createElement('a');
      	        a.href = canvas.toDataURL('png');
      	        a.download = 'myfile.png';
      	        a.click();
    
    	       //Clean up everything after image is done being made
   		artDivDOM.style.position = "absolute";
  		artDivDOM.style.left = tempLeft;
  		artDivDOM.style.top = tempTop;
  })`

tks this solution has resolved my problem

@S-Fahmy
Copy link

S-Fahmy commented Mar 29, 2021

I was facing the same problem, but setting scrollY: 0 didn't fix it. I ended up fixing it by reversing the vertical scroll with window.scrollY, like this:

{
    scrollX: 0,
    scrollY: -window.scrollY
}

As this is quite a hack it would be really great having this issue fixed! Cheers 🍻

This worked perfectly!

@bilibiliou
Copy link

bilibiliou commented Apr 20, 2021

My solution:
my version: html2canvas: "1.0.0-rc.7"

const { width, height } = $dom.getBoundingClientRect();
const { x, y } = getPosition($dom);
const defaultOptions: Partial<html2canvasOptions> = {
  useCORS: true,
  backgroundColor: null,
  width,
  height,
  x,
  y,
}

const oCanvas = await html2canvas($dom, defaultOptions);

getPosition: get the element postion relative to root

export const getPosition = element => {
  const currentTop = window.pageXOffset;
  const currentLeft = window.pageYOffset;

  if (element) {
    if (element.getBoundingClientRect) {
      const { top, left } = element.getBoundingClientRect();
      return { x: left + currentLeft, y: top + currentTop };
    } else {
      // polyfill
      let xPosition = 0;
      let yPosition = 0;

      while (element) {
        xPosition += element.offsetLeft - element.scrollLeft + element.clientLeft;
        yPosition += element.offsetTop - element.scrollTop + element.clientTop;
        element = element.offsetParent;
      }
      return { x: xPosition, y: yPosition };
    }
  }

  return {
    x: 0,
    y: 0,
  };
};

This worked perfectly in my project!

@ivictbor
Copy link

ivictbor commented May 1, 2021

@if anyone can't predict whether target captured element will be inside of fixed or non-fixed and affected by window scroll I recommend a solution which we used for Painterro js paint plugin: devforth/painterro@bfee94d#diff-9745fe0b9d3e6feae056f29a5730e6fe548b33695e8968628fcd717c1e9ad03aR203

Thing is that I've fixed it by setting scrollY to -window.scrollY like it was suggested above, but then the reporter tried fixed position: devforth/painterro#137 . I think the cloning way is more universal approach, plus it does not require IE11 specific properties

@youlinaa
Copy link

youlinaa commented May 4, 2021

version: 1.0.0-rc.7

const { top, left } = el.getBoundingClientRect()

const res = await html2canvas(el, {
  scale: 2,
  x: left,
  y: top
})

it works!

@nelsoneldoro
Copy link

nelsoneldoro commented May 19, 2021

wait a little works for me!

version: 1.0.0-rc.7

const sleep = async (ms) => {
  return await new Promise((resolve) => setTimeout(resolve, ms));
};

html2canvas(this.chartContentRef.current, {
  onclone: async (doc) => {
    await sleep(500);
  },
})
.then((canvas) => {
  download(canvas)
});

@kirnehv
Copy link

kirnehv commented Jul 3, 2021

  1. Solution for IOS Safari blank on scroll...

CSS:

.rootDiv {
  overflow-x: hidden;
}

JS Function:

html2canvas(element , {
      scrollX: 0,
      scrollY: -window.scrollY
})

...of course, overflow-x: hidden may cause other undesirable outcomes.

  1. Another solution for IOS Safari blank on scroll...

CSS:

.element {
  position: fixed;
}

JS Function:

html2canvas(element , {
      scrollX: 0,
      scrollY: 0
})

@AhmedMuhammedElsaid
Copy link

this solution works
html2canvas(domNode, { scrollX: 0, scrollY: -window.scrollY })

@policiadestiny
Copy link

Você pode adicionar os seguintes estilos à caixa:
position: fixed; left: 0; top: 0;
e então,configuração html2Canvas:
{ scrollY: 0 }

@dhanesh-dev
Copy link

window.scrollTo(0, 0);
worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.