Search code examples
javascriptjquerycsshtml2canvascanvg

Try find best solution to make OpenLayers map screenshot using html2canvas. The map elements losing css classes, images don't viewed


So, i know about bad work html2canvas with css. Maybe somebody can help me find best solution. I need make map screenshot with elements. After screenshot i'll getting an image, looks pretty good, but in html all elements(panels, buttons) of map losing all css classes and images don't viewed.

So, what i was trying: reload div of map by js/jquery; reload stylesheets; move css classes from "myFile.css" to html;

I think that useless for me.

Once i'm trying move cssText to style attribute of elements, and it's worked good, but i think getting and rewrite all elements from div and his childs bad idea.


Solution

  • The problem was that the pictures were a svg, it was necessary to use XMLSerializer(), and i think sometimes html2canvas bad working with layouts of primeFaces, so if you have problem with css that fixed by importNode. Working for me:

    //don't forget to declare all js libs and files on html page
    
    //targetElem - id of map, like a $('#map')
    function screenshotMap(targetElem) {
    
    var nodesToRecover = [];
    var svgElem = targetElem.find('svg');
    var serializer = new XMLSerializer();
    
    //screenshotAreaId - north layoutUnit of layout this variable need for                    
    //"update" north layoutUnit
    var oldNode = document.getElementById("screenshotAreaId");
    
    //convert all svg's to canvas, filling an arrays for turn back canvas to svg
    svgElem.each(function (index, node) {
    
        var parentNode = node.parentNode;
        //skip nested svg's in "parent" svg, canvg will handle "parent"
        if(parentNode.tagName != 'DIV'){
        return true;
        }
        var canvas = document.createElement('canvas');
        var svg = parentNode.querySelector('svg');
        var svgString = serializer.serializeToString(svg);
    
        //canvg lib
        canvg(canvas, svgString);
    
        nodesToRecover.push({
            parent: parentNode,
            child: node
        });
    
        parentNode.removeChild(node);
        parentNode.appendChild(canvas);
    });
    
    //html2canvas lib, "screenshot map" download file
    html2canvas(targetElem, {
        onrendered: function (canvas) {
            var img = canvas.toDataURL('image/png').replace("image/png",  "image/octet-stream");
            window.location.href = img;
    
            //removing canvas, turn back svg's
            var canvasElem = targetElem.find('canvas');
            canvasElem.each(function (index, node) {
                var parentNode = node.parentNode;
                parentNode.removeChild(node);
                parentNode.appendChild(nodesToRecover[index].child);
            });
    
            //"update" layoutUnit if you have problems with css
            var newNode = document.importNode(oldNode, true);
            document.getElementById("layout").appendChild(newNode);
        }
    });
    }
    

    You will find canvg here: https://github.com/gabelerner/canvg

    You will find html2canvas here: http://html2canvas.hertzen.com/