Currently I am trying to create screenshot functionality of a Geospatial map
Below I have achieved to get the Geospatial map as a screenshot, where as I need to add few divs from outside the Geospatial on top of the map.
// create canvas
const layoutCanvas = document.createElement("canvas");
const context = layoutCanvas.getContext("2d");
layoutCanvas.height = imageData.height;
layoutCanvas.width = imageData.width;
// add the image to the canvas
context.putImageData(imageData, 0, 0);
//Capture Top Layout
const captureElement = document.getElementById('viewDiv')
html2canvas(captureElement, { allowTaint: true })
.then(canvas => {
canvas.style.display = 'none'
const p2 = new Promise((resolve, reject) => {
//Find all External divs
var divs = document.getElementsByClassName('jBox-wrapper');
var processCount = 0;
for (var i = 0; i < divs.length; i++) {
if (divs[i].getAttribute('class').includes('jBox-wrapper')) {
//console.log(divs[i].outerHTML);
pinArea = divs[i].getBoundingClientRect();
var data = 'data:image/svg+xml,' +
encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml">' + divs[i].outerHTML + '</div></foreignObject></svg>')
const tempImg = document.createElement('img')
tempImg.src = data;
console.log(tempImg.src)
tempImg.onload = function () {
context.drawImage(tempImg, pinArea.x, pinArea.y);
processCount++;
if (processCount == divs.length) {
resolve("Success!");
}
}
}
}
})
p2.then((value) => {
if (value == "Success!") {
document.body.appendChild(canvas)
console.log(canvas)
return canvas
}
})
})
.then(canvas => {
//context.drawImage(canvas, 0, 0);
const image1 = layoutCanvas.toDataURL('image/png');
const a1 = document.createElement('a')
a1.setAttribute('download', fileName)
a1.setAttribute('href', image1)
a1.click()
layoutCanvas.remove()
})
The basic screenshot functionality is working except the external div.
The logic in question is in Promise p2. Can I add external div's this way or need another approach.
Any help would be great. Thank you.
html2canvas
is responsible for inlining external styleSheets (hence the promise). The way I'd go about it is create a new DOMNode and clone both the map and the overlay into it. Then inline all the stylesheets. From there you have enough to add to aforeignObject
and create a screenshot. I've created a simple example here jsfiddle.net/Sjeiti/2f9gvma5 The only this missing is adding the external stylesheets (around thetry...catch
). – Toomey