Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG textpath, determine when text goes beyond the path

Tags:

html

text

path

xml

svg

I have got the below code to display text along a path. I am planning to make sort of dynamic where I can just type in what i want and it displays it along the path. Haven't worked out how to do that yet, any suggestions would be mostly welcome.

However my question is, how do I find out exactly at what point the text goes beyond the end of the path and no longer display. The idea is when I have it working dynamically, if the user types a sentence longer than what the path can handle, it will tell you that the text will be cut off from a certain point. in this case the user only sees the words "The quick brown fox jum", the fore I want the error message to say "ps over the lazy dog" could not be displayed or at least at a minimum to the say "The sentence is too long, and is not displayed in full"

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg viewBox = "0 0 500 300" version = "1.1">
    <defs>
      <path id = "s3" d = "M 10,90 Q 100,15 200,70 "/>
    </defs>
    <g>
        <text font-size = "20">
            <textPath xlink:href = "#s3">
                The quick brown fox jumps over the lazy dog                
            </textPath>
        </text>
        <use x = "0" y = "0" xlink:href = "#s3" stroke = "black" fill = "none"/>
    </g>
</svg>
like image 559
Dinesh Avatar asked Jul 23 '11 12:07

Dinesh


2 Answers

You can query the computed lengths of the string that should go on the path, and the length of the path. Then compare the two, if the string length is longer than the path length then text will fall off the path.

You can also use the knowledge of the path length to squeeze the string to fit, like this:

<svg viewBox="0 0 500 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
      <path id="s3" d="M 10,90 Q 100,15 200,70 "/>
    </defs>
    <g>
        <text font-size="20">
            <textPath xlink:href="#s3" textLength="204" lengthAdjust="spacingAndGlyphs">
                The quick brown fox jumps over the lazy dog                
            </textPath>
        </text>
        <use x="0" y="0" xlink:href="#s3" stroke="black" fill="none"/>
    </g>
</svg>

Here's an example where the string length is manipulated by decreasing the font-size:

<svg viewBox="0 0 500 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
      <path id="s3" d="M 10,90 Q 100,15 200,70 "/>
    </defs>
    <g>
        <text font-size="20" font-family="Arial,Helvetica,sans-serif">
            <textPath id="tp" xlink:href="#s3" lengthAdjust="spacingAndGlyphs">
                The quick brown fox jumps over the lazy dog
            </textPath>
        </text>
        <use x="0" y="0" xlink:href="#s3" stroke="black" fill="none"/>
    </g>
    <script><![CDATA[
        var textpath = document.getElementById("tp");
        var path = document.getElementById("s3");
        var fontsize = 20;
        while (textpath.getComputedTextLength() > path.getTotalLength())
        {
            fontsize -= 0.01;
            textpath.setAttribute("font-size", fontsize);
        }
    ]]></script>
</svg>
like image 133
Erik Dahlström Avatar answered Sep 28 '22 02:09

Erik Dahlström


align

  • set <path id="#P" pathLength="100" ...>

    • https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/pathLength
  • set <textPath href="#P" startoffset="100" text-anchor="end">

    • https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-anchor

pathLength on other elements works in FireFox, not on Chromium (march 2021)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 40">
  <rect width="100%" height="100%" fill="beige"></rect>
  <path id="P" pathLength="100" d="M20 20h160" stroke="blue"></path>
  <text>
    <textPath href="#P" 
              startoffset="0" 
              text-anchor="start">start</textPath>
  </text>
  <text>
    <textPath href="#P"
              startoffset="50" 
              dominant-baseline="hanging"
              text-anchor="middle">middle</textPath>
  </text>
  <text>
    <textPath href="#P" 
              startoffset="100" 
              text-anchor="end">end</textPath>
  </text>
</svg>
like image 23
Danny '365CSI' Engelman Avatar answered Sep 28 '22 03:09

Danny '365CSI' Engelman