使用SVG和JS创建弯曲文本 [英] Creating Curved Text with SVG and JS

查看:74
本文介绍了使用SVG和JS创建弯曲文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Javascript在SVG中创建弯曲的文本.我遇到了很多问题,特别是与名称空间相关的问题,但是现在一切正常,成功显示了路径和圆,但是未显示文本.当我在浏览器检查器中复制粘贴创建的svg代码并将其添加到svg时,它会按预期工作.但是我无法使用JS使其工作.整个代码如您所见:

I want to create curved text in SVG using Javascript. I have faced a lot of problems, specially the namespace related ones, but now everything works, a path and a circle are successfully shown, but the text is not displayed. When I copy-paste the created svg code in browser inspector and add that to the svg, it works as intended. But I can't make it work using JS. The whole code is as you can see:

<html>
<body onload="onLoad()">
    <div id="svgbox"></div>
</body>

<script>
var svg;
var last_shape; // for debug 


function qs(sel)
{
    return document.querySelector(sel);
}


function SVG(el)
{
    this.element = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    qs(el).appendChild(this.element);

    var props = {   
                    "xmlns": "http://www.w3.org/2000/svg",
                    "xmlns:xlink": "http://www.w3.org/1999/xlink",
                    "version": "1.1",
                    "style": "width:100%;height:100%;",
                    "stroke": "#58b",
                    "fill":"none",
                    "stroke-width": "2"
                };

    for (i in props) {
        this.element.setAttribute(i, props[i]);
    }

    this.create = function(tag,props) {
        var o = document.createElementNS("http://www.w3.org/2000/svg", tag);

        if(typeof(props)!="undefined") {
            for (i in props) {
                o.setAttribute(i, props[i]);
            }
        }

        return o;

    }

    this.add = function(tag,props) {
        var o = this.create(tag,props);

        this.element.appendChild( o ); 
        return o;
    };

    this.addTo = function(parent, tag, props) {
        var o = document.createElementNS("http://www.w3.org/2000/svg", tag);

        if(typeof(props)!="undefined") {
            for (i in props) {
                o.setAttribute(i, props[i]);
            }
        }

        parent.appendChild(o);

        return o;

    };

    return this;
}



function drawArc(svg, fromX, fromY, toX, toY, controlX, controlY, props)
{
    var o = svg.add( "path",    {
                            "d":"M" + fromX + " " + fromY + " Q " +
                                    controlX + " " + controlY + " " +
                                    toX + " " + toY
                        });

    if(typeof(props)!="undefined") {
        for (i in props) {
            o.setAttribute(i, props[i]);
        }
    }
    last_shape = o;

    return o;
}

function drawLabeledArrow(svg, fromX, fromY, toX, toY, title, props)
{
    var arc_id = "arc-"+Math.floor(Math.random()*10000000);
    var arc = drawArc( svg, fromX, fromY, toX, toY, (fromX+toX)/2, (fromY+toY)/2 - (fromX+toX)/2, {id: arc_id});
    var head_base_x = arc.getPointAtLength(arc.getTotalLength() - 4).x;
    var head_base_y = arc.getPointAtLength(arc.getTotalLength() - 4).y;


    last_shape = svg.add("text");   
    last_shape = svg.addTo(last_shape, "textPath", {"fill":"#ff0000", "xlink:href":"#"+arc_id});    
    last_shape.appendChild(document.createTextNode(title));

    last_shape = svg.add( "circle",     {
                                                    cx: head_base_x,
                                                    cy: head_base_y,
                                                    r: 4,
                                                    fill: "#5ad"
                                                });


}



function onLoad() 
{
    svg = SVG('#svgbox');

    drawLabeledArrow(svg, 10,100, 200, 100, "test label");
}
</script>

</html>

如果有人告诉我这里出了什么问题,以及在JS中使用SVG时对所有这些问题有任何简短的解释,我将不胜感激.谢谢.

I'd appreciate if anyone tells me what's wrong here, and if there is any good and short explanation of all these problems in working with SVG in JS. Thanks.

更新:我修改了代码以改为使用setAttributeNS,但仍然没有成功.

UPDATE: I modified the code to use setAttributeNS instead, but still no success.

function drawLabeledArrow(svg, fromX, fromY, toX, toY, title, props)
{
    var arc_id = "arc-"+Math.floor(Math.random()*10000000);
    var arc = drawArc( svg, fromX, fromY, toX, toY, (fromX+toX)/2, (fromY+toY)/2 - (fromX+toX)/2, {id: arc_id});
    var head_base_x = arc.getPointAtLength(arc.getTotalLength() - 4).x;
    var head_base_y = arc.getPointAtLength(arc.getTotalLength() - 4).y;


    last_shape = svg.add("text");   


    var o = document.createElementNS("http://www.w3.org/2000/svg", "textPath");

    o.setAttributeNS("http://www.w3.org/2000/svg", "xlink:href", "#"+arc_id);
    o.appendChild(document.createTextNode(title));

    last_shape.appendChild( o ); 



    last_shape = svg.add( "circle",     {
                                                    cx: head_base_x,
                                                    cy: head_base_y,
                                                    r: 4,
                                                    fill: "#5ad"
                                                });


}

推荐答案

不能使用setAttribute设置xlink:href属性,因为该方法只能在null命名空间中设置属性,而xlink:href在xlink命名空间中.

The xlink:href attribute cannot be set with setAttribute as that method can only set attributes in the null namespace and xlink:href is in the xlink namespace.

改为使用setAttributeNS并指定xlink命名空间 http://www.w3.org/1999/xlink 作为第一个参数.

Use setAttributeNS instead and specify the xlink namespace http://www.w3.org/1999/xlink as the first argument.

这篇关于使用SVG和JS创建弯曲文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆