Jump to content

Search In
  • More options...
Find results that contain...
Find results in...

Center dynamic text around curved path

Recommended Posts

Hi ! :D
I'm pretty new to SVG and struggling on some parts.
I don't know how to center around a text path properly.
To make it embrace the curved path, with dynamic length text (can be 5 letters or 25).

I took @sdrasner workshop which was really helpful to gather some things quickly !
There are some cool things that I gathered on SVG Text Layout by Kurt Cagle blog post suggesting to use inlineSize.
More Robust SVG Text was another resource, then I've tried startOffset="50%" text-anchor="middle"

But none of them were giving me exactly what I wanted because the most important thing here is the width of the SVG text.

Sarah talked (video #45) about a way of doing it with  `stroke-dashoffset: -274` and with something like `document.querySelector('svg path')[0].getTotalLength()` but I do not get how the 2 can work in my case.
The closest thing that I've achieved is this: TextPathAttributes, in pair with some ugly `tspan` as shown in my codepen...

Yep, you guessed it, at that point I'm totally lost on what to try and I have to admit that the official documentation is pretty hard to get a grip on (too much things that I may not need ever)...

So, to sum up my mess above, I want to:
- get a centered text with something around 80/90% of the total arc width
- wrap a longer sentence on 2 lines (the height static on the arc can stay static ofc)
- still keep it responsive on desktop/mobile (should be ok since it's SVG)
- as my draw below suggests, it will be on some kind of wheel and the text should keep the orientation aka face the opposite side of the center of the wheel
- as far as I understood, I will not need DrawSVGPlugin, right ? ?


See the Pen QoGxgG?editors=1010 by kissu (@kissu) on CodePen

Link to comment
Share on other sites

That's a deep dive into SVG.


I played around a bit I could get it to work with 2 separate text items but couldn't manage to line things up with tspans in the same text item regardless of how I adjusted x,y,dx,dy. Of course bear in mind I didn't have clue what I was doing.


If you're working with dynamic text maybe you could add some logic to split your strings to write to multiple text items?


Then again maybe someone will come along that actually knows about this and has a real solution?


See the Pen oVdNMg by Visual-Q (@Visual-Q) on CodePen


Found a discussion on STOV about inserting breaks with svg text spans might point you in the right direction.





  • Like 3
Link to comment
Share on other sites

Hi @kissu,


Welcome to the GreenSock Forum.


For me it's easier to build such layouts completely in INKSCAPE. The text is finally converted to paths.
Before doing so, make sure you have a copy to make changes to the text later.


See the Pen eXrzvK by mikeK (@mikeK) on CodePen


Happy tweening ...




  • Like 2
Link to comment
Share on other sites

I'm not gonna dive too deep into the weeds here since you're new to SVG and this isn't really a GSAP question. SVG text is a bit of beast and cross browser consistency is a fantasy. SVG text is tough enough, but when you start adding textPath and textLength into the mix it gets even more frustrating. For example, animating textLength is different in FF and Chrome on a textPath. Chrome will only animate the textLength of the textPath element, but FF will only animate the textLength of the actual text element & Edge won't work at all


Here's a quick example:

See the Pen vRzmeO by PointC (@PointC) on CodePen


Even when you're not using a textPath, Edge is a nightmare to use with textLength. I had to get creative animating some text from the center here:


See the Pen oqPxYr by PointC (@PointC) on CodePen

Here's a thread I wrote about the two demos above.

You're also throwing another layer of complexity in here trying to intelligently break lines of text into multiple levels on the same wedge. I'm not sure how I'd approach that. I'd have to think about it a little more. Here's a demo in which I broke apart SVG text and measured the size of each character's BBox so I could explode the words. 


See the Pen jpEdBd by PointC (@PointC) on CodePen


Maybe the above info will point you in the right direction or give you some ideas.  What you're trying to do is not trivial and cross browser support will be tricky. If you have limited variations of text, I'd recommend @mikel's approach and create the paths ahead of time in your vector software. If the text is dependent on some user input and variations are therefore unlimited, this will be a bit of a challenge. 


Hopefully that helps a bit. Happy tweening.



  • Like 2
Link to comment
Share on other sites

@mikel thanks for the welcome. ^^ 
Unfortunately, your solution is kinda not a possibility since the project I'm working on is essentially a Vue app that will fetch the data on Firebase (I'm not planning of having any kind of backend actually).
So, every piece of text can be modified on the fly and it will also have a "you chose that quarter, ok ! now I will remove it from the wheel and expand the other quarters accordingly". The whole point is to make a lot of things dynamic as you can see. GSAP will add that tasty animations on top of all ! :D

@Visual-Q hm, I'm a bakka, just realized that `tspan` do have a `textLength` and `lengthAdjust` attributes...
After some reading, the official doc says 


[TextLength] is not intended for use to obtain effects such as shrinking or expanding text.

I guess I still will use it like that... Because, `text-anchor` and `startOffset` are not working as expected in my case 90...
Damn ! Expected to have a `tspan-center-align: middle` or something native. ?

I will use `getTotalLength`, get the total length of a path, then strip 10% of it on both sides, add a "margin" of 10% with `x` or `dx`, that will give me a centered text, independently of the number of words, in pair with `lengthAdjust="spacingAndGlyphs"`, the result seems to be really great as this example shows.
I will of course try to find a clever way to split the text into multiple lines with increasing numbers of chars for each line (coming from the center of the wheel).

For the vertical alignment, I will simply make the computations to get a smaller radius and the path will pretty much vertical center it by itself.
Oh and all of this will be less dirty thanks to Vue ! :D

@PointC I'm pretty much not in charge of Edge support, so I can totally dish it out like it does not even exist.


For the text split part, I will try to find a naive implementation, I do essentially have 3 or 4 words of various length to split on 2 lines, not soooo hard to deal with I guess. I guess GSAP cannot help me on that part (in case I do have more complex texts) ? ?
Also sorry if my questions are not really GSAP related but are more about general SVG. ?

Thanks for the help guys ! ? 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.