SVG 中的多行弯曲文本

发布于 2024-10-19 22:29:58 字数 1731 浏览 0 评论 0原文

SVG 中是否有一种方法可以在单个 元素中绘制遵循相同路径轮廓的多行文本?这是我能得到的最接近的结果:

<?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 xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
        <path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
    </defs>
    <use xlink:href="#text_0_path" stroke="blue" fill="none"/>
    <text font-family="Arial" font-size="18px" text-anchor="middle">
        <textPath xlink:href="#text_0_path" startOffset="50%">
            <!-- 157.075 is the center of the length of an arc of radius 100 -->
            <tspan x="157.075">Here is a line</tspan>
            <tspan x="157.075" dy="20">Here is a line</tspan>
            <tspan x="157.075" dy="20">Here is a line</tspan>
        </textPath>
    </text>
</svg>

这是输出(在 Chrome 中):

Curved text

这是 几乎我想要的。问题:

  • 我希望每行文本都以弧线顶部为中心,而不是从那里开始文本。当沿路径在 tspan 中指定 x 值时,似乎会忘记 text-anchor 属性。 (对于直文本来说,情况并非如此;会记住 text-anchor 属性。)
  • 每个连续的文本行都会被压缩,就好像遵循同心路径一样。我希望每行文本都遵循相同的轮廓,就好像路径只是通过字体的高度在 y 方向上平移一样。

我知道我可以创建三个单独的 元素,并将它们与三个单独的 (或 ) 元素,但是使用 元素将所有文本逻辑地保留在一起以供以后的应用程序使用会非常好。

或者这应该可以工作,但 Chrome 中存在渲染错误? (不太可能,国际海事组织)

Is there a way in SVG of drawing multiple lines of text within a single <text> element that follow the same path contour? Here is the closest I have been able to get:

<?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 xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
        <path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
    </defs>
    <use xlink:href="#text_0_path" stroke="blue" fill="none"/>
    <text font-family="Arial" font-size="18px" text-anchor="middle">
        <textPath xlink:href="#text_0_path" startOffset="50%">
            <!-- 157.075 is the center of the length of an arc of radius 100 -->
            <tspan x="157.075">Here is a line</tspan>
            <tspan x="157.075" dy="20">Here is a line</tspan>
            <tspan x="157.075" dy="20">Here is a line</tspan>
        </textPath>
    </text>
</svg>

Here is the output (in Chrome):

Curved text

This is almost what I want. The problems:

  • I would like each line of text centered at the top of the arc, not to start the text there. It seems like the text-anchor attribute is being forgotten when the x value is specified in a tspan along a path. (This is not the case with straight text; the text-anchor attribute is remembered.)
  • Each successive line of text is crunched, as if following a concentric path. I would like each line of text to follow the same contour, as if the path were simply translated in the y direction by the height of the font.

I know I could just create three separate <path> elements and associate them with three separate <text> (or <textPath>) elements, but it would be really nice to keep all the text logically together using <tspan> elements for later applications.

Or is this supposed to work but there is a rendering bug in Chrome? (unlikely, IMO)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

两个我 2024-10-26 22:29:58

我不知道您是否希望将文本呈现在同心圆上,或者您只是希望将其翻译。如果是前者,那么您可能需要在 t-span 元素上尝试字母间距属性。这将为您的角色添加跟踪,将它们推得更远。我尝试了以下操作,但由于某种原因,线之间的对齐丢失了:

<?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 xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
        <path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
    </defs>
    <use xlink:href="#text_0_path" stroke="blue" fill="none"/>
    <text font-family="Arial" font-size="18px" text-anchor="middle">
        <textPath xlink:href="#text_0_path" startOffset="50%">
            <!-- 157.075 is the center of the length of an arc of radius 100 -->
            <tspan x="157.075">Here is a line</tspan>
            <tspan x="157.075" dy="20" letter-spacing="2">Here is a line</tspan>
            <tspan x="157.075" dy="20" letter-spacing="4">Here is a line</tspan>
        </textPath>
    </text>
</svg>

但是,如果您想要后者(同心圆),这似乎适用于 Mac 上的 Safari 和 Chrome:

<?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 xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
        <path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
    </defs>
    <use xlink:href="#text_0_path" stroke="blue" fill="none"/>
    <g font-family="Arial" font-size="18px">
        <text text-anchor="middle">
            <textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
        </text>
        <text text-anchor="middle" transform="translate(0, 20)">
            <textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
        </text>
        <text text-anchor="middle" transform="translate(0, 40)">
            <textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
        </text>
    </g>
</svg>

我知道您只拍摄 tspans,但作为你说,它似乎重置了 startOffset 值。

哈特哈,
凯文

I can't tell if you want the text rendered on concentric circles or if you simply want it translated. If the former, then you may want to experiment with letter-spaccing attributes on your t-span elements. This will add tracking to your characters pushing them further apart. I tried the following, but alignment between lines is lost for some reason:

<?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 xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
        <path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
    </defs>
    <use xlink:href="#text_0_path" stroke="blue" fill="none"/>
    <text font-family="Arial" font-size="18px" text-anchor="middle">
        <textPath xlink:href="#text_0_path" startOffset="50%">
            <!-- 157.075 is the center of the length of an arc of radius 100 -->
            <tspan x="157.075">Here is a line</tspan>
            <tspan x="157.075" dy="20" letter-spacing="2">Here is a line</tspan>
            <tspan x="157.075" dy="20" letter-spacing="4">Here is a line</tspan>
        </textPath>
    </text>
</svg>

However, if you want the latter (concentric circles), this appears to work in Safari and Chrome on the Mac:

<?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 xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
        <path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
    </defs>
    <use xlink:href="#text_0_path" stroke="blue" fill="none"/>
    <g font-family="Arial" font-size="18px">
        <text text-anchor="middle">
            <textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
        </text>
        <text text-anchor="middle" transform="translate(0, 20)">
            <textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
        </text>
        <text text-anchor="middle" transform="translate(0, 40)">
            <textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
        </text>
    </g>
</svg>

I know you were shooting for tspans only, but as you said, it seemed to reset the startOffset values.

HTH,
Kevin

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文