0

Trying to put a Text Path on a Text element in SVGJS, but I want to use an existing Path instead of SVGJS creating an additional Path element in the defs section that I have to update.

The reason for this is that I have a (text) label that appears on a line, which can be dragged around, and I would like to be able to have the native SVG do this, rather than also having to update the text path on the element as well.

So currently SVG.JS will do this

<defs>
  <path id="SvgjsPath0010" d="M0,0L100,100" />
</defs>
....
<g>
  <path id="SvgjsPath1234 d="M0,0L100,100" />
  <text>
    <textPath id="SvgjsTextPath0011" href="#SvgjsPath0010">
      A Label
    </textPath>
  </text>
</g>

What I want to achieve is to do this in SVG.JS is simply use the path element above as the TextPath...

<g>
  <path id="SvgjsPath1234 d="M0,0L100,100" />
  <text>
    <textPath id="SvgjsTextPath0011" href="#SvgjsPath1234">
      A Label
    </textPath>
  </text>
</g>

I've tried to pass the Path object, but no-go, and the documentation is a bit flimsy on this one. I've tried this already;

var path = mySvgGroup.path('M0,0L100,100');

var line = mySvgGroup.text('A Label');
line.path( path );

But doesn't seem to like it.

My best option at the moment I think is to build the Text element manually, but would prefer a quicker, cleaner option.

Any suggestions?

1 Answer 1

1

In svg.js v2 there is no good way to reuse a path for textPaths. Unfortunately the implementation does not follow the behavior of clip or mask where you just can pass in your object you want to reuse.

This issue is fixed in svg.js v3. We are hard working to release it soon. However until then you can just use this fixed version:

SVG.extend(SVG.Text, {
  path: function(d) {
    // create textPath element
    var path  = new SVG.TextPath
    var track

    if (d instanceof SVG.Path) {
      track = d
    } else {
      track = this.doc().defs().path(d)
    }

    // move lines to textpath
    while (this.node.hasChildNodes())
      path.node.appendChild(this.node.firstChild)

    // add textPath element as child node
    this.node.appendChild(path.node)

    // link textPath to path and add content
    path.attr('href', '#' + track, SVG.xlink)

    return this
})

Actually the fix is so tiny we might backport it to v2 :)

Now you can just pass in a Path

Sign up to request clarification or add additional context in comments.

1 Comment

Ended up using the svgobj.textPath().attr('href', '#svgjsOTHERPATH'), which works like a dream, but leaves an extra unused path (unless I clean that), but wanted to make sure I wasn't missing anything. Fantastic library though, keep up the fantastic work and thank you so much for patch. :D

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.