有可能使用javascript将2个SVG文件混合在一起产生HTML / HTML5吗?

时间:2014-03-26 15:30:32

标签: javascript html5 svg

我正在创建一个使用嵌入式浏览器显示SVG文件的软件(带有SVG的HTML / HTML5)。

许多SVG文件会有很多共同点,所以我希望避免将该部分复制到所有SVG文件中。我想提供一个扩展/包含的基本SVG。让我们调用基础SVG" base.svg"。

我在SVG中搜索了类似INCLUDE的内容,但它并不存在。

是否可以创建一个包含HTML5链接元素的HTML文件,或者包含base.svg的javascript代码? 然后,我只是将其余的SVG放入HTML中。像这样(伪):

<html>
<body>
    <link rel="import" href="base.svg" />
    <!-- or some javascript code to include the base.svg content -->

    <svg>
        <!-- The rest of the SVG -->
    </svg>
</body>
</html>

有可能吗? 如果没有,使用PHP服务器(或类似的东西)动态生成完整的SVG(result = base.svg + rest.svg)是不错的选择?

非常感谢。

===解决方案(基于Francis Hemsher方法):

HTML文件:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Combine/Parse SVG Files via XML DOM</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='padding:0px;font-family:arial'>
    <center>
        <h4>Combine/Parse SVG Files via XML DOM</h4>
        <div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
            Load svg files as XML via <b>XMLHttpRequest</b>. Parse the Document Elements to create a client's file.
            This example first loads the <b>Base.svg</b> inline into a DIV, then extracts/adds elements from another <b>companion</b> svg file,
            combining them into a seamless svg root.
        </div>
        <br />
        Base + Companion SVG:
        <textarea id=svgValue style='width:90%;height:100px;font-size:120%;font-family:lucida console;'></textarea>
        <div id="svgDiv" style='background-color:white;width:400px;height:400px;' ></div>
        <br />
        Parameters:
        <br />
        <textarea id=jsParams style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:40px'></textarea>
        <br />
        Javascript:
        <br />
        <textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea>
    </center>

<script id="parameterRetrieval">
    var params = new Array();

    function queryParameters() {
        var query = window.location.search.substring(1);
        var lParams = query.split('&');
        for (var i = 0; i < lParams.length; ++i) {
            var pos = lParams[i].indexOf('=');
            if (pos > 0) {
                var key = lParams[i].substring(0, pos);
                var val = lParams[i].substring(pos + 1);
                params[key] = val;
                console.log("params[ " + key + " ] = \"" + val + "\"");
            }
        }
    }

    function getParameterByName(key) {
        return params[key];
    }
</script>

<script id="SVGComposer">   
    var  XMLdoc;

    function loadCompanionXML() {
        // Element inside the base SVG file to hold the companion SVG content.
        var destElement = getParameterByName("destination");
        // Companion SVG name.
        var SVGFile = getParameterByName("svg");
        if (SVGFile == null) {
            console.log("Missing parameter: child svg file (svg).");
            return;
        }
        var loadXML = new XMLHttpRequest;
        function handler() {
            if ((loadXML.readyState == 4) && (loadXML.status == 200)) {
                var childSVG = document.getElementById(destElement);
                if (childSVG != null) {
                    childSVG.innerHTML = loadXML.responseText;
                    svgValue.value=svgDiv.innerHTML;
                } else {
                    console.log("Could not get the child SVG container.");
                }
            }
        }
        if (loadXML != null) {
            loadXML.open("GET", SVGFile, true);
            loadXML.onreadystatechange = handler;
            loadXML.send();
        }
    }

    document.addEventListener("onload", init(), false);
    function init() {
        queryParameters();

        var SVGFile = "base.svg";
        var loadXML = new XMLHttpRequest;
        function handler() {
            if ((loadXML.readyState == 4) && (loadXML.status == 200)) {
                svgDiv.innerHTML = loadXML.responseText;
                loadCompanionXML();
            }
        }
        if (loadXML != null) {
            loadXML.open("GET", SVGFile, true);
            loadXML.onreadystatechange = handler;
            loadXML.send();
        }

        jsValue.value = SVGComposer.text;
    }
</script>

</body>
</html>

base.svg:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="w3.org/1999/xlink" id="baseSVG" width="400" height="400" fill="white">
    <circle r="50" fill="green" cx="50" cy="50" stroke="none" />
    <g id="childSVG" />
</svg>

companion.svg:

<defs>
    <image id="bkimage" xlink:href="http://placepuppy.it/320/240" width="100%" height="100%" />
    <rect id="MyRect" width="100" height="100" stroke="black" stroke-width="2" />
</defs>

<g>
    <defs>
        <mask id="image1mask" ><polygon points="0,0, 320,0, 160,120, 320,240, 0,240" fill-opacity="30%" /></mask>
    </defs>
<use xlink:href="#bkimage" mask="url(#image1mask)"/>
</g>
<use xlink:href="#MyRect" x="100" y="100" fill="red" />
<use xlink:href="#MyRect" x="150" y="150" fill="blue" />
<use xlink:href="#MyRect" x="200" y="200" fill="green" />
<g>
    <defs>
        <clipPath id="MyRectClip"><rect x="270" y="270" width="60" height="60" /></clipPath>
    </defs>
    <rect x="250" y="250" width="100" height="100" stroke="black" stroke-width="2" fill="yellow" clip-path="url(#MyRectClip)"/>
</g>

要加载它,您应该打开以下网址:

http://theHTMLfile?svg=companion.svg&destination=childSVG

Ps:我知道图像蒙版的坐标不能很好地工作。忽略这一点。这只是一个考验。 干杯!

1 个答案:

答案 0 :(得分:2)

我假设您可以访问XML DOM。如果是这样,合并svg的最佳方法是通过xml dom方法。

EDIT (added below) UPDATE: added xlink namespace, needed for image elements

以下是将svg文件合并到客户端上的单个内联svg的非常基本的方法。它可以通过XML DOM组合/解析SVG文件。

通过XMLHttpRequest将svg文件作为XML加载。解析文档元素以创建客户端文件。 此示例首先将 Base.svg 内联加载到DIV中,然后从另一个 companion.svg 文件中提取/添加元素, 将它们组合成一个无缝的svg根。

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Combine/Parse SVG Files via XML DOM</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    </head>
    <body style='padding:0px;font-family:arial'>
    <center><h4>Combine/Parse SVG Files via XML DOM</h4>
    <div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
    Load svg files as XML via <b>XMLHttpRequest</b>. Parse the Document Elements to create a client's file.
    This example first loads the <b>Base.svg</b> inline into a DIV, then extracts/adds elements from another <b>companion</b> svg file,
    combining them into a seamless svg root.
    </div>
    <br />Base + Companion SVG:
    <textarea id=svgValue style='width:90%;height:200px;font-size:120%;font-family:lucida console;'></textarea>
    <div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;' ></div>
    <br />Javascript:<br />
    <textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea>
    </center>

    <script id=myScript>
    /*


Base.svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="baseSVG" width="400" height="400">
<circle r="50" fill="green" cx="100" cy="100" stroke="none" />
</svg>

companion.svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="companionSVG">
<rect x="180" y="200" width="200" height="150" fill="red" />
<ellipse cx="70" cy="300" rx="65" ry="25" fill="blue" />
<image x="120" y="100"  xlink:href="myImage.png" width="198" height="65" />
</svg>

    */
    //--onload---
    function loadBaseSVGInline()
    {
        var SVGFile="Base.svg"
        var loadXML = new XMLHttpRequest;
        function handler(){
            if(loadXML.readyState == 4 && loadXML.status == 200)
            {
                svgDiv.innerHTML=loadXML.responseText
                loadCompanionXML()
            }
        }
        if (loadXML != null){
            loadXML.open("GET", SVGFile, true);
            loadXML.onreadystatechange = handler;
            loadXML.send();
        }
    }
    var  XMLdoc
    function loadCompanionXML()
    {
        var SVGFile="companion.svg"
        var loadXML = new XMLHttpRequest;
        function handler()
        {
            if(loadXML.readyState == 4 && loadXML.status == 200)
            {
                //---responseText---
                var xmlString=loadXML.responseText
                //---DOMParser---
                var parser = new DOMParser();
                XMLdoc=parser.parseFromString(xmlString,"text/xml").documentElement;
                companionXML2Base()
            }
        }
        if (loadXML != null){
            loadXML.open("GET", SVGFile, true);
            loadXML.onreadystatechange = handler;
            loadXML.send();
        }
    }
    //--place companion elements into base
    function companionXML2Base()
    {
        var mySVG=document.getElementsByTagName("svg")[0]
        var elems=XMLdoc.childNodes
        for(var k=0;k<elems.length;k++)
        {
            var elem=elems.item(k).cloneNode(true)
            mySVG.appendChild(elem)
        }

        svgValue.value=svgDiv.innerHTML

    }
    </script>
    <script>
    document.addEventListener("onload",init(),false)
    function init()
    {
        loadBaseSVGInline()
        jsValue.value=myScript.text
    }
    </script>
    </body>
    </html>