Reputation: 101
I use html2canvas to save a webpage as an image and i'd like to get the same results on a mobile and a PC. My webpage has a table that renders differently on a smaller screen (via CSS). I would like html2canvas to save the canvas as if the webpage is always on a PC screen. This way the table on the webpage will always look the same.
I currently have a workaround which temporarily sets the body width and viewport initial-scale to something larger before html2canvas runs, saves the webpage, then reverts back to the previous body width and viewport scale. The code I use is at the bottom of this post.
It mostly works but has a bad user experience because during the html2canvas operation the webpage will grow larger, pause for a bit (during the save) then revert back. Which doesn't look very good from the users point of view. Also, this doesn't always work for every mobile device.
Is there a better way to do this? Can I have some sort of off screen html that mirrors my on screen html but will always render as if its on a PC?
// adjust screen and viewport to allow all table elements to fit on the screen correctly
document.body.style.width = '1024px';
let viewport = document.querySelector("meta[name=viewport]");
let remembered_viewport = JSON.stringify(viewport.outerHTML)
viewport.setAttribute('content', 'width=device-width, initial-scale=2');
// use html2canvas to save the webpage
let tag = document.getElementById("all");
html2canvas(tag).then(function(canvas) {
let link = document.createElement("a");
link.download = filename.toLowerCase();
canvas.toBlob( function(blob) {
link.href = URL.createObjectURL(blob);
link.click();
}, 'image/jpg');
});
// reset screen and viewport
document.body.style.width = "auto";
if (remembered_viewport.includes("initial-scale=0.5")) viewport.setAttribute('content', 'width=device-width, initial-scale=0.5');
if (remembered_viewport.includes("initial-scale=2")) viewport.setAttribute('content', 'width=device-width, initial-scale=2');
else viewport.setAttribute('content', 'width=device-width, initial-scale=1');
Thanks in advance, Jason.
Upvotes: 4
Views: 3658
Reputation: 101
Thanks to CBroe I did get it working using an off screen iframe. As follows:
// capture my on screen html
let html = document.documentElement.outerHTML;
// create the iframe
// there is css to push it off screen (ie. left: -1024px;)
let iframe = document.createElement("iframe");
iframe.style.width = "1024px";
iframe.style.height = "100%";
document.body.appendChild(iframe);
// add html to iframe
iframe.srcdoc = html;
// wait for iframe to load
iframe.addEventListener("load", () => {
// use html2canvas to save the webpage
html2canvas(iframe.contentWindow.document.body).then(function(canvas) {
let filename = "image.jpg";
let link = document.createElement("a");
link.download = filename.toLowerCase();
canvas.toBlob( function(blob) {
link.href = URL.createObjectURL(blob);
link.click();
}, 'image/jpg');
});
});
I do need to remove the iframe after the iframe is loaded AND the image is saved, but the basics appear to work without any odd on screen size changes.
Upvotes: 4