The issue arose from using SVG images, requiring the use of XMLSerializer(). It seems that html2canvas may encounter difficulties with PrimeFaces layouts at times, and problems with CSS can be resolved by importNode. Here is a solution that worked for me:
// Make sure to include all necessary JS libraries and files in the HTML page
//targetElem - ID of the map element, such as $('#map')
function screenshotMap(targetElem) {
var nodesToRecover = [];
var svgElem = targetElem.find('svg');
var serializer = new XMLSerializer();
//screenshotAreaId - ID of the north layoutUnit where the screen capture will be displayed
var oldNode = document.getElementById("screenshotAreaId");
//Convert all SVG elements to canvas, storing them in an array for later conversion back to SVG
svgElem.each(function (index, node) {
var parentNode = node.parentNode;
//Skip nested SVGs within parent SVGs, as canvg will handle the parent SVG
if(parentNode.tagName != 'DIV'){
return true;
}
var canvas = document.createElement('canvas');
var svg = parentNode.querySelector('svg');
var svgString = serializer.serializeToString(svg);
//Using the canvg library
canvg(canvas, svgString);
nodesToRecover.push({
parent: parentNode,
child: node
});
parentNode.removeChild(node);
parentNode.appendChild(canvas);
});
//Using the html2canvas library to create a screenshot of the map and download it
html2canvas(targetElem, {
onrendered: function (canvas) {
var img = canvas.toDataURL('image/png').replace("image/png", "image/octet-stream");
window.location.href = img;
//Removing the canvas and converting back to SVG
var canvasElem = targetElem.find('canvas');
canvasElem.each(function (index, node) {
var parentNode = node.parentNode;
parentNode.removeChild(node);
parentNode.appendChild(nodesToRecover[index].child);
});
//Updating the layoutUnit if there are CSS issues
var newNode = document.importNode(oldNode, true);
document.getElementById("layout").appendChild(newNode);
}
});
}
You can find the canvg library here: https://github.com/gabelerner/canvg
You can find the html2canvas library here: