2

For svg.js I wrote a little plugin adding textPath functionality. The plugin is very concise:

// textpath plugin
SVG.TextPath = function() {
    this.constructor.call(this, SVG.create('textPath'))
}
SVG.TextPath.prototype = new SVG.Element
SVG.extend(SVG.TextPath, {
    text: function(text) {
        while (this.node.firstChild) this.node.removeChild(this.node.firstChild)
        this.node.appendChild(document.createTextNode(text))
        return this
    }
})
SVG.extend(SVG.Text, {
    path: function(d){
        var textPath = new SVG.TextPath().text(this.content)

        while (this.node.firstChild) this.node.removeChild(this.node.firstChild)

        this.track = this.doc().defs().path(d)
        this.node.appendChild(textPath.node)
        textPath.attr('xlink:href', '#' + this.track)

        return this
    }
})

To create the same output as this example on MDN, the plugin can be used as follows:

// example usage
var draw = SVG('canvas').viewbox(0, 0, 1000, 300)

var text = draw.text('We go up, then we go down, then up again')
text.font({ size: 42.5, family: 'Verdana' })
text.path('M 100 200 C 200 100 300  0 400 100 C 500 200 600 300 700 200 C 800 100 900 100     900 100')

draw.use(text.track).attr({ fill: 'none', 'stroke-width': 1, stroke: '#f09' })

Here is a fiddle of the dynamic version: http://jsfiddle.net/wout/LNuWM/

But this is where it goes wrong because the text is not rendered. At first I thought something was wrong with my code but when I copied the svg output from the inspector and pasted in a svg document, the text is rendered as expected.

Here an example of the static version: http://jsfiddle.net/wout/ZbM7K/

Is this a browser glitch or am I missing something?

UPDATE: This has now been resolved: http://jsfiddle.net/wout/LNuWM/2/

1 Answer 1

2

This seems to be an error in SVG.js. The SVG root element gets messed up because of adding the XLink namespace:

<svg style="position:relative;overflow:hidden;left:0px;top:0px;"xlink="http://www.w3.org/1999/xlink" ...
---------------------------------------------------------------^
|
--------this should read [SPACE]xmlns:xlink=
Sign up to request clarification or add additional context in comments.

2 Comments

As it turns out it was a combination of two mistakes, both to do with wrong usage of namespaces. The xlink declaration in svg.js was set linke this attr('xmlns:xlink', SVG.xlink, SVG.ns) instead of attr('xlink', SVG.xlink, SVG.ns), which is obviously the correct way. Additionally, the xlink:href attribute on the textPath was set with setAttribute instead of setAttributeNS, so I changed this attr('xlink:href', '#' + this.track) to attr('href', '#' + this.track, SVG.xlink). That did the trick. The textPath implementation is now part of svg.js: jsfiddle.net/wout/yfGjF
Ah, the good ol' setAttributeNS. I am not very unhappy, that I rarely need it at my dayjob. (Although I quite like XML namespaces.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.