how to save/ export inline SVG styled with css from browser to image file

johowie picture johowie · Mar 3, 2013 · Viewed 12.4k times · Source

I have a web app that is generating inline SVG graphics in the client on the fly based on user interaction. The graphic is defined partly by element attributes and partially by CSS classes and id's.

I would like to be able to provide an option for the client to save a copy of the inline SVG as either a bitmap or an .svg image file. It is important that all styles are applied from the external css styling files. How can I provide this functionality to save as either as .svg or bitmap (.gif) preferably in the browser using javascript or else on the server with node.js ?

Answer

hsc picture hsc · May 23, 2016

Why not copying the SVG node/tree and then take the styles, as defined per tag (You will need the original tree, as the copy may be without styles in case the element is part of a longer tree). This ensures that you are only copying those styles relevant as set in the CSS file. The export type could easily be set before sending the package to the blob

var ContainerElements = ["svg","g"];
var RelevantStyles = {"rect":["fill","stroke","stroke-width"],"path":["fill","stroke","stroke-width"],"circle":["fill","stroke","stroke-width"],"line":["stroke","stroke-width"],"text":["fill","font-size","text-anchor"],"polygon":["stroke","fill"]};


function read_Element(ParentNode, OrigData){
    var Children = ParentNode.childNodes;
    var OrigChildDat = OrigData.childNodes;     

    for (var cd = 0; cd < Children.length; cd++){
        var Child = Children[cd];

        var TagName = Child.tagName;
        if (ContainerElements.indexOf(TagName) != -1){
            read_Element(Child, OrigChildDat[cd])
        } else if (TagName in RelevantStyles){
            var StyleDef = window.getComputedStyle(OrigChildDat[cd]);

            var StyleString = "";
            for (var st = 0; st < RelevantStyles[TagName].length; st++){
                StyleString += RelevantStyles[TagName][st] + ":" + StyleDef.getPropertyValue(RelevantStyles[TagName][st]) + "; ";
            }

            Child.setAttribute("style",StyleString);
        }
    }

}

function export_StyledSVG(SVGElem){


    var oDOM = SVGElem.cloneNode(true)
    read_Element(oDOM, SVGElem)

    var data = new XMLSerializer().serializeToString(oDOM);
    var svg = new Blob([data], { type: "image/svg+xml;charset=utf-8" });
    var url = URL.createObjectURL(svg);

    var link = document.createElement("a");
    link.setAttribute("target","_blank");
    var Text = document.createTextNode("Export");
    link.appendChild(Text);
    link.href=url;

    document.body.appendChild(link);
}