SVG_text.动态创建&换行显示(横)

 

1、我的测试代码

  1.1、

<?xml version="1.0" encoding="UTF-8"?>
<svg width="1000" height="800" viewBox="-500 -200 1000 800" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:cge="http://iec.ch/TC57/2005/SVG-schema#" xmlns:hzsvg="http://holleygrid.cn/svg">

    <script type="text/javascript" >
    <![CDATA[
    <!--

    var g_iTextSpanIdx = 0;
    function TextWordwrap_Horizontal(_eleText, _eleText_hidden, _iWidth, _strNS, _strText)
    {
        if (_strText.length <= 0)
            reeturn;

        g_iTextSpanIdx = 0;
        _eleText.innerHTML = "";

        // ZC: 还要将 _eleText_hidden的属性设置成和_eleText的属性 一样的 (font-size / font-family 等)

            _eleText_hidden.innerHTML = "";
            var nodeText_hidden = document.createTextNode(_strText[0]);
            _eleText_hidden.appendChild(nodeText_hidden);

        var iFirstSpanHeight = 0;// ZC: _eleText中第一行<span/>的高度
        var iPrevSpanWidth = 0;// ZC: _eleText中上一行<span/>的宽度

        if (_strText.length > 1)
        {
            var iCntPrev = 0;
            var eleTspan = null;
            var nodeText = null;

            for (var i=1; i<_strText.length; i++)
            {
                var iWidthPrev = _eleText_hidden.getComputedTextLength();

                iCntPrev = _eleText_hidden.firstChild.data.length;
                _eleText_hidden.firstChild.data += _strText[i];

                if (_eleText_hidden.getComputedTextLength() > _iWidth)
                {
                        console.log("i : " + i);
                        console.log("iWidthPrev : " + iWidthPrev + " , " + _eleText_hidden.getComputedTextLength());
                        console.log("iCntPrev : " + iCntPrev);

                    _eleText_hidden.firstChild.data = _eleText_hidden.firstChild.data.slice(0, iCntPrev);

                    eleTspan = document.createElementNS(_strNS, "tspan");
                    _eleText.appendChild(eleTspan);
                    nodeText = document.createTextNode(_eleText_hidden.firstChild.data);
                    eleTspan.appendChild(nodeText);

                    if (g_iTextSpanIdx == 0)
                    {
                        var rt = _eleText.getBBox();
                        iFirstSpanHeight = rt.height;

                            console.log("iFirstSpanHeight : " + iFirstSpanHeight);
                    }
                    else
                    {
                        eleTspan.setAttribute("dx", (-iPrevSpanWidth) + "");
                        eleTspan.setAttribute("dy", (iFirstSpanHeight) + "");

                            console.log("dx : " + (-iPrevSpanWidth) + " , " + g_iTextSpanIdx);
                            console.log("dy : " + (iFirstSpanHeight));
                    }

                    _eleText_hidden.firstChild.data = _strText[i];
                    iPrevSpanWidth = iWidthPrev;
                    g_iTextSpanIdx ++;

                        console.log("");
                }// if
            }// for

            if (iCntPrev > 0)
            {
                eleTspan = document.createElementNS(_strNS, "tspan");
                _eleText.appendChild(eleTspan);
                nodeText = document.createTextNode(_eleText_hidden.firstChild.data);
                eleTspan.appendChild(nodeText);

                eleTspan.setAttribute("dx", (-iPrevSpanWidth) + "");
                eleTspan.setAttribute("dy", (iFirstSpanHeight) + "");
            }
        }// if
    }

        window.onload = function(evt)
        {
        var strTextContent = "中文测试text内容。中文测试text内容。中文测试text内容。中文测试text内容。中文测试text内容。中文测试text内容。";
    //    var strTextContent = "中文测试text内";
        var eleSvg = document.getElementsByTagName("svg")[0];
        var strNS = eleSvg.getAttribute("xmlns");
        
        var eleText = document.createElementNS(strNS, "text");
        eleSvg.appendChild(eleText);

        eleText.setAttribute("x", "-400");
        eleText.setAttribute("y", "0");

        var textCalcLength = document.getElementById("textCalcLength");

        TextWordwrap_Horizontal(eleText, textCalcLength, 200, strNS, strTextContent);
        //TextWordwrap_Horizontal(eleText, 100);
        };
    -->
    ]]>
    </script>


<rect x="-400" y="-30" width="200" height="1" stroke="none" fill="blue"/>


<!--  visibility="hidden" -->
<text id="textCalcLength" visibility="hidden" />

  
</svg>
<?DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"?>

 

 

2、网上搜索到的 方案的源码:

<?xml version="1.0" encoding="UTF-8"?>
<svg width="1000" height="800" viewBox="-500 -200 1000 800" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:cge="http://iec.ch/TC57/2005/SVG-schema#" xmlns:hzsvg="http://holleygrid.cn/svg">

    <script type="text/javascript" >
    <![CDATA[
    <!--

    var width = 200;

    function init(evt)
    {
        if ( window.svgDocument == null )
        {
            svgDocument = evt.target.ownerDocument;
        }
        create_multiline("Whatever text you want here.");
    }

    function create_multiline(text)
    {
        var words = text.split(' ');                        
        var text_element = svgDocument.getElementById('multiline-text');
        var tspan_element = document.createElementNS(svgNS, "tspan");   // Create first tspan element
        var text_node = svgDocument.createTextNode(words[0]);           // Create text in tspan element

        tspan_element.appendChild(text_node);                           // Add tspan element to DOM
        text_element.appendChild(tspan_element);                        // Add text to tspan element

        for(var i=1; i<words.length; i++)
        {
            var len = tspan_element.firstChild.data.length;             // Find number of letters in string
            tspan_element.firstChild.data += " " + words[i];            // Add next word

            if (tspan_element.getComputedTextLength() > width)
            {
                tspan_element.firstChild.data = tspan_element.firstChild.data.slice(0, len);    // Remove added word

                var tspan_element = document.createElementNS(svgNS, "tspan");       // Create new tspan element
                tspan_element.setAttributeNS(null, "x", 10);
                tspan_element.setAttributeNS(null, "dy", 18);

                text_node = svgDocument.createTextNode(words[i]);
                tspan_element.appendChild(text_node);
                text_element.appendChild(tspan_element);
            }
        }
    }

        window.onload = function(evt)
        {
        svgNS = "http://www.w3.org/2000/svg";
        //svgDocument = document.documentElement;// 这个就是 <svg/>节点
        svgDocument = document;
        create_multiline("Whatever text you want here.1234567890.1234567890");


        var text01 = document.getElementById("text01");
        var rt = text01.getBBox();
        console.log(rt.x+", "+rt.y+", "+rt.width+", "+rt.height+" - "+text01.tagName);

        var text0101 = document.getElementById("text0101");
        rt = text0101.getBBox();
        console.log(rt.x+", "+rt.y+", "+rt.width+", "+rt.height+" - "+text0101.tagName);

        var text0102 = document.getElementById("text0102");
        rt = text0102.getBBox();
        console.log(rt.x+", "+rt.y+", "+rt.width+", "+rt.height+" - "+text0102.tagName);
        };

    -->
    ]]>
    </script>


<text x="10" y="50" id="multiline-text"> </text>
<rect x="10" y="30" width="200" height="1" fill="none" stroke="red"/>

<text x="-100" y="200" id="text01" >
    <tspan id="text0101">Whatever text you want</tspan>
    <tspan id="text0102" dx="0" dy="21">here. 1234567890.1234567890</tspan>
</text>

</svg>
<?DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"?>

 

3、根据上面 “2、网上搜索到的 方案的源码” 修改的适合我需要的方案的源码

<?xml version="1.0" encoding="UTF-8"?>
<svg width="1000" height="800" viewBox="-500 -200 1000 800" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:cge="http://iec.ch/TC57/2005/SVG-schema#" xmlns:hzsvg="http://holleygrid.cn/svg">

    <script type="text/javascript" >
    <![CDATA[
    <!--

    // ZC: _eleText里面必须是未分过行的内容,不然 计算位置会出错
    function TextWordwrap_Horizontal(_eleText, _iWidth)
    {
        // ZC: 直接获取<text/>的文本内容 (innerText)
        //var str = _eleText.innerText;
        var str = _eleText.firstChild.data;
        if (str.length <= 0)
            return;
        _eleText.innerHTML = "";

        var eleSvg = document.getElementsByTagName("svg")[0];
        var strNS = eleSvg.getAttribute("xmlns");

        var eleTspan = document.createElementNS(strNS, "tspan");
        _eleText.appendChild(eleTspan);
        var nodeText = document.createTextNode(str[0]);
        eleTspan.appendChild(nodeText);

        var rtText = _eleText.getBBox();
        console.log("_eleText.getBBox() : " + rtText.x + ", " + rtText.y + ", " + rtText.width + ", " + rtText.height);

        var iRowCnt = 0;
        if (str.length > 1)
        {
            for(var i=1; i<str.length; i++)
            {
                var rtShort = eleTspan.getBBox();
                console.log("rtShort.width : "+ rtShort.width);

                var iLen = eleTspan.firstChild.data.length;
                console.log("iLen : " + iLen);
                eleTspan.firstChild.data += str[i];    

                var rtLong = eleTspan.getBBox();
                console.log("rtLong.width : "+ rtLong.width);

                if (rtLong.width > _iWidth)
                {
                    iRowCnt ++;
                    eleTspan.firstChild.data = eleTspan.firstChild.data.slice(0, iLen);

                    eleTspan = document.createElementNS(strNS, "tspan");
                    _eleText.appendChild(eleTspan);
                    nodeText = document.createTextNode(str[i]);
                    eleTspan.appendChild(nodeText);

                    var rtTspan = eleTspan.getBBox();
    // ZC: 这里计算 dx(x轴的偏移)时,由于本tspan的偏移位置是相对于上一个tspan而言的,又∵每次的上一个tspan的宽度不一定一样,
    // ZC:    如果 偏移了之后 比 <text/>的x还小的话,就会导致 整个<text/>的宽度变大,就会出现 本文件执行时出现的不对的现象
                    eleTspan.setAttribute("dx", (-rtShort.width) + "");
                    console.log("(-rtShort.width) : "+ (-rtShort.width));
                    eleTspan.setAttribute("dy", (rtText.height * iRowCnt) + "");
                    console.log("(rtText.height*iRowCnt) : "+ (rtText.height*iRowCnt) + " , " + rtText.height);
                }


            }
        }
    }
    // ZC: <tspan/> 的宽度 就是 == <text/>的宽度?

        window.onload = function(evt)
        {
        var strTextContent = "中文测试text内容。中文测试text内容。中文测试text内容。中文测试text内容。中文测试text内容。中文测试text内容。";
        var eleSvg = document.getElementsByTagName("svg")[0];
        var strNS = eleSvg.getAttribute("xmlns");
        var nodeText = document.createTextNode(strTextContent);
        

        var eleText = document.createElementNS(strNS, "text");
        //var eleText = document.createElement("text");
        eleSvg.appendChild(eleText);
        console.log("eleText : " + eleText);

        eleText.appendChild(nodeText);

        var rtText = eleText.getBBox();
        console.log(rtText.x + ", " + rtText.y + ", " + rtText.width + " , " + rtText.height);
        // ZC: just 文本

        TextWordwrap_Horizontal(eleText, 100);

        };
    -->
    ]]>
    </script>


<rect x="0" y="-30" width="100" height="1" stroke="none" fill="blue"/>


<text id="textCalcLength" visibility="hidden" />

  
</svg>
<?DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"?>

 

4、

5、

 

posted @ 2018-08-26 15:45  Html5Skill  阅读(2008)  评论(0编辑  收藏  举报