Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG textpath text layout on complex, changing paths

Tags:

svg

I am not sure the problem I have is solvable using the current SVG standard but I thought I would ask here anyway if anyone knows an answer

I have a constantly changing svg path (vertices defined by forming a hull around nodes made in d3, force driven so the nodes constantly move and the bounding hull moves to accomodate the nodes)

Because I can't predict the vertices nor do I know what the text will be (as it depends on the grouping of the nodes in that situation, which changes) all i can do is blindly apply text on a textpath to the path. The problemis sometimes the text does not display nicely.

Problem 1: upside down text - I don't mind where on the path the text goes but its annoying that it often ends up upside down

For example (image):

enter image description here

[NB Problem 2 branched into SVG textpath rendering breaks words up badly on a textpath with sharp corners as suggested in answer]

Problem 2: broken up text - when a corner forms, text has a tendency to split. up. I don't think my use of dy to push the text outside the boundary helps (the path is actually tight to the nodes and I apply a 40 stroke-width to give some padding: the dy pushed the text outside that stroke)

For example (image):

enter image description here

Any ideas on what I can do to fix this?

--Chris

svg code for reference:

Problem 1:

<g id="hull_elements">
<path class="boundary" id="Secure"     d="M219.31353652066463,309.7274362305448L199.3259715998452,277.60331505353355L54.5215284230899,92.9756148805194L29.418010605669316,64.72387260525474Z" style="fill: #b0c4de; stroke: #b0c4de; stroke-width: 40px; stroke-linejoin: round;"></path>
<path class="boundary" id="DMZ" d="M234.7675515627913,79.25604751762172L122.76947855325542,190.1418483839412L271.90702281166267,76.40758102069142Z" style="fill: #b0c4de; stroke: #b0c4de; stroke-width: 40px; stroke-linejoin: round;"></path>
</g>
<g id="hull_text">
<text dy="30"><textPath startOffset="0" text-anchor="start" method="align" spacing="auto" xlink:href="#Secure">Secure</textPath></text>
<text dy="30"><textPath startOffset="0" text-anchor="start" method="align" spacing="auto" xlink:href="#DMZ">DMZ</textPath></text>
</g>

Problem 2:

<g id="hull_elements"><path class="boundary" id="Secure" d="M30.716331539726912,88.02778447495649L66.8405337274694,100.01086904278971L251.78816229874747,53.214214251587265L277.8704519199028,25.642491075146587Z" style="fill: #b0c4de; stroke: #b0c4de; stroke-width: 40px; stroke-linejoin: round;"></path>
<path class="boundary" id="DMZ" d="M177.8575710153683,149.56053657599713L251.04637461899244,245.55658992744486L277.76418020025847,271.7261370009561L159.53295211932644,118.0340968521715Z" style="fill: #b0c4de; stroke: #b0c4de; stroke-width: 40px; stroke-linejoin: round;"></path>
</g>
<g id="hull_text">
<text dy="30"><textPath startOffset="0" text-anchor="start" method="align" spacing="auto" xlink:href="#Secure">Secure</textPath></text>
<text dy="30"><textPath startOffset="0" text-anchor="start" method="align" spacing="auto" xlink:href="#DMZ">DMZ</textPath></text>
</g>

jsfiddle to play with that shows this (move the nodes to see the issues) http://jsfiddle.net/zuzzy/GC2C2/

[edited to add the NB of the branch of problem 2 - zuzzy]

like image 574
zuzzy Avatar asked Mar 06 '26 21:03

zuzzy


1 Answers

For problem 1 I think you need to detect when the x co-ordinates are moving to the left and draw the path back to front in that case.

If you have

M 0,0 L 100, 0

that's OK 100 > 0 so leave it as it is. But

M 100, 0 L 0,0

has 0 < 100 so that would need reversing. In this case reversing would give us the path in the first case.

Here's a complete example.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <path id="MyPath"
          d="M 300 200 
             L 100 200" />
    <path id="MyPathReversed"
          d="M 100 200 
             L 300 200" />
  </defs>
  <desc>Example toap01 - simple text on a path</desc>

  <g transform="translate(0, 100)">
    <text font-family="Verdana" font-size="42.5" fill="blue" >
      <textPath xlink:href="#MyPath">
        upside down
      </textPath>
    </text>
  </g>

  <text font-family="Verdana" font-size="42.5" fill="blue" >
    <textPath xlink:href="#MyPathReversed">
      right way up
    </textPath>
  </text>

</svg>

BTW I suggest you ask problem 2 as a separate question.

like image 120
Robert Longson Avatar answered Mar 10 '26 11:03

Robert Longson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!