I'm using html2canvas to create images from the DOM element.
The code looks like this.
const node = document.getElementById('domElement')
html2canvas(node, {
windowWidth: node.scrollWidth,
windowHeight: node.scrollHeight,
}).then(canvas => {
const image = canvas.toDataURL()
})
But its only rendering an image that is fully white. The image size (l*b) is accurate.
But when I try to render the image of the full body it shows the image but with blank white screen on top.
i.e. when,
const node = document.body
How will the elements be added properly and not the blank white screen on the image?
The code is inside an antd design modal.
This statement solved my problem.
window.scrollTo(0, 0)
The final code looks like
window.scrollTo(0, 0)
const node = document.getElementById('domElement')
html2canvas(node, {
windowWidth: node.scrollWidth,
windowHeight: node.scrollHeight,
}).then(canvas => {
const image = canvas.toDataURL()
})
Related
I am trying to download the entire contents of a div including the overflow using html2canvas, but the image is always cropped.
Here is a fiddle link with example code:
https://jsfiddle.net/50x2gfne/1/
function grab() {
const captureElement = document.querySelector('#capture')
html2canvas(captureElement)
.then(canvas => {
canvas.style.display = 'none'
document.body.appendChild(canvas)
return canvas
})
.then(canvas => {
const image = canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')
const a = document.createElement('a')
a.setAttribute('download', 'my-image.png')
a.setAttribute('href', image)
a.click()
canvas.remove()
})
capture.style.oveflow = 'scroll'
}
I have tried changing the width of the html and body to a wider size, setting the viewport wider, and changing the width of the canvas function.
I also tried the method in the following link for handling horizontal overflow with no luck:
https://blog.logrocket.com/export-react-components-as-images-html2canvas/
I am using html2canvas to get the image of an html element(input[type='text']).
I have a control which increases the font size of the text field, and also the size of the field to accomodate the text in it.
Before changing the font, html2canvas gets the image of the field and its contents correctly. But when the font size increases, the image is not fully shown again.
I have put a red border around the canvas and the gray border is the one around the html element being snapped.
Here is the code that takes the snapshot:
function snapElem(el) {
function hiddenClone(element){
// Create clone of element
let clone = element.cloneNode(true);
// Position element relatively within the
// body but still out of the viewport
let 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;
}
// Clone element
let clone = hiddenClone(el);
clone.id = "za-clone-id-"+new Date().getTime();
// Use clone with htm2canvas and delete clone
html2canvas(clone, {
backgroundColor:null,
allowTaint: true,
useCORS: true
}).then(function (canvas) {
canvas.style.border = '2px solid red';
console.log(canvas.toDataURL());
canvas.id = "za-real-id-"+new Date().getTime();
document.body.removeChild(clone);
document.querySelector(".body-right").appendChild(canvas);
}).catch((e) => {
// Handle errors
console.log(e);
});
}
Here are the images obtained as the font size of the field changes
How can the content remain centered within the canvas when the font size changes.
The page has no scrolling.
So I am trying to set attributes (width and height) of my all images on page.
So i do something like that:
const images = document.querySelectorAll('img');
const setImagesAttributes = () => {
images.forEach(img => {
img.setAttribute('width', img.clientWidth);
img.setAttribute('height', img.clientHeight);
})
}
window.onload = () => {
setImagesAttributes();
window.addEventListener('resize', debounce(setImagesAttributes));
}
And now something weird happen. So I think 90% of images work correct, the behave in same way like before adding script. But some images have very low height, idk what happend. Why one image behave normally, others not.
Before adding script:
After script:
But as i sad over 90% of images works correct. After adding script they have W & H attributes and work fine
I have a Vue component, in it I have an img, I need to get that image dimensions, preferably before showing the image (to fit in the container either by width or height).
this.img = new Image();
this.img.src = this.payload.src;
this.img.onload = () => {
let width = this.img.naturalWidth;
let height = this.img.naturalHeight;
}
That code might not work, the image src can return 401 (not sure yet), we use proxy and get that file from a storage bucket on the server. like /api/getStorageResource?blob=
What can I do?
Having the link, can I somehow fetch image through axios and set it as an element, instead of <img src=".." />
As an option I see that I can probably have the element as it is now <img src="/api/getStorageResource?blob=" /> and getElementById it and get the width and height... Not sure what my options here.
You can use a combination of async/await and the fetch api inside a try/catch block to get the image URL from your server and then you can proceed with creating the <img> element, assign the retrieved image URL to the img element src and finally set the width and height of the container equal to the img element's width and height.
In the following example Code Snippet, I have added a button which will add the image to the container on click so you can see how the container has the retrieved image dimensions even before the image is rendered on the DOM:
const imgDiv = document.querySelector('#imgDiv');
const btn = document.querySelector('#imgBtn');
//The fetchImg function will fetch the image URL from the server and log error to console if file not found
const fetchImg = async () => {
try {
// replace the following example url with "this.payload.src"
const imgURL = await fetch('https://picsum.photos/id/237/200/200');
return imgURL;
} catch (err) {
// do something here if image not found
console.log('Image not found!');
}
}
fetchImg().then((res) => {
// create a new image element with the URL as the src
const img = new Image();
img.src = res.url; // change ".url" according to how the data you get from your server is structured
// assign the retrieved width and height of img to container
img.addEventListener('load', () => {
imgDiv.style.width = img.naturalWidth + 'px';
imgDiv.style.height = img.naturalHeight + 'px';
});
btn.addEventListener('click', () => imgDiv.appendChild(img));
});
html, body {margin: 0;padding: 10px;width: 100%; height: 100%;text-align: center;}
#imgDiv {background-color: #222;margin: 0 auto;}
<button id="imgBtn">Add Image</button>
<div id="imgDiv"></div>
JSFiddle with above code: https://jsfiddle.net/AndrewL64/2hu3yxtq/104/
I'm using Trianglify to create backgrounds for a div element. I wanted to write the function to regenerate the background anytime the window is resized.
Here is the function that adds the generated png to the div.
const header = document.querySelector('#header');
const addBackground = target =>{
const dimensions = target.getClientRects()[0];
const pattern = Trianglify({
width: dimensions.width,
height: dimensions.height,
cell_size: Math.random()*200 + 40
});
target.style['background-image'] = 'url(' + pattern.png() + ')';
}
addBackground(header);
And here is the ResizeObserver
const ro = new ResizeObserver( () => {
addBackground(header);
});
ro.observe(header);
This works fine in chrome and edge but it creates an effect in FireFox where the background image isn't generated until the user is done resizing. This would be fine if it didn't clear the background during the resizing.
I've created a fiddle that recreates the issue.
Link to Fiddle