skip to Main Content

I want to align the middle of the text with the top of a circle. I’m using <path> and <textpath> to render the text along the circular path in the svg. The startOffset attribute helps to achieve it but I want to calculate it in js. Here is the svg code:

<svg id="svg" width="500" height="500">
<defs><path d="M 180 200
    m -100, 0
    a 100,100 0 1,1 200,0
    a 100,100 0 1,1 -200,0
    " id="pathSlf6u6uz93">
    </path>
</defs>
<text x="50" y="50">
<textPath xlink:href="#pathSlf6u6uz93">Curved text testing</textPath>
</text>
<path d="M 180 200
    m -100, 0
    a 100,100 0 1,1 200,0
    a 100,100 0 1,1 -200,0
    " style="" fill="rgba(0,0,0,0)" stroke="#000000">
</path>
</svg>

Here is the solution using startOffset. The only issue is that I don’t know how to calculate.

<svg id="svg" width="500" height="500">
<defs><path d="M 180 200
    m -100, 0
    a 100,100 0 1,1 200,0
    a 100,100 0 1,1 -200,0
    " id="pathSlf6u6uz93">
    </path>
</defs>
<text x="50" y="50">
<textPath xlink:href="#pathSlf6u6uz93" startOffset="45">Curved text testing</textPath>
</text>
<path d="M 180 200
    m -100, 0
    a 100,100 0 1,1 200,0
    a 100,100 0 1,1 -200,0
    " style="" fill="rgba(0,0,0,0)" stroke="#000000">
</path>
</svg>

My end goal is to achieve text curve like in canva.
enter image description here

2

Answers


  1. In the following example I’ve marked the begining of the path with a small circle.

    I gather that you need to center the text around the point at 25% of the path length.

    In order to do this I’ve temoved the x and y attributes of the text and set the startOffset="25%". Also I use text-anchor="middle". This is centering the text around the desired point. No need of JS. You can now change the radius of the circle and the text will stay centered where you need it to be.

    d="M 180 200
            m -R, 0
            a R,R 0 1,1 200,0
            a R,R 0 1,1 -200,0"
    
    <svg id="svg" width="500" height="500">
    <defs><path d="M 180 200
        m -100, 0
        a 100,100 0 1,1 200,0
        a 100,100 0 1,1 -200,0
        " id="pathSlf6u6uz93">
        </path>
    </defs>
    <text>
    <textPath xlink:href="#pathSlf6u6uz93" startOffset="25%" text-anchor="middle">Curved text testing</textPath>
    </text>
    <use href="#pathSlf6u6uz93"
         style="" fill="rgba(0,0,0,0)" stroke="#000000">
    </use>
    <circle cx="80" cy="200" r="3" />
    </svg>

    Please observe that I’m using a <use> element instead of redrawing the path.

    Login or Signup to reply.
  2. Addendum to Enxaneta his answer, you can set pathLength on the <path> and position with relative notation

    <svg id="svg" width="500" height="500">
    <defs>
      <path id="p1" pathLength="4" d="M180 100m-100,0a100,100 0 1,1 200,0a100,100 0 1,1-200,0"/>
    </defs>
    <text>
    <textPath href="#p1" startOffset="2" text-anchor="middle">Curved text testing</textPath>
    </text>
    <use href="#p1" fill="pink" stroke="#000000" />
    <circle cx="80" cy="200" r="3" />
    </svg>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search