多行文本的跨浏览器 textPath 水平居中对齐

Cross-browser textPath horizontal centre alignment for multi-line text

我想水平居中对齐多行文本。

以下方法适用于 Firefox 68.0.2

path { stroke: #000; }
text { fill: #000; } 
<svg width="400" height="120">
  <path id="p1" d="M10,40l250,0" />
  <text text-anchor="middle">
    <textPath href="#p1" startOffset="50%">
      <tspan x="0" dy="1.4em">this is the first line</tspan>
      <tspan x="0" dy="1.4em">and this is the second</tspan>
    </textPath>
  </text>
</svg>

但是,在 Chrome 版本 77.0.3865.90 中,两行都呈现在左侧。看起来好像是用两者的总长度<tspan>来计算中心点。

我可以通过使用两个单独的 <text> 元素使其在两种浏览器中工作:

path { stroke: #000; }
text { fill: #000; }
<svg width="400" height="120">
  <path id="p1" d="M10,40l250,0" />
  <text text-anchor="middle">
    <textPath href="#p1" startOffset="50%">
      <tspan x="0" dy="1.4em">this is the first line</tspan>          
    </textPath>
  </text>
  <text text-anchor="middle">
    <textPath href="#p1" startOffset="50%">
      <tspan x="0" dy="2.8em">and this is the second</tspan>
    </textPath>
  </text>
</svg>

(我也尝试在同一个 <text> 父级中使用两个 <textPath>,但是 dy 的行为在两个浏览器之间也不同)

我的问题是:

  1. 哪个浏览器运行正常(这是另一个浏览器的错误)吗?
  2. 是否有一种跨浏览器的方法可以在不渲染两个单独的 <text> 元素的情况下实现相同的结果?

我相信 Chrome 在这里做的是正确的 - 除了缺少 "a"。 :-/

在 SVG 1.1 中,startOffsetx 属性的交互没有很好地定义,浏览器做了所有不同的事情。

但是,在 SVG 2 中,已尝试完整描述 <textPath> 元素的文本布局算法。你可以在这里找到它:

https://svgwg.org/svg2-draft/single-page.html#text-TextpathLayoutRules

里面写着:

For text-anchor:middle, startpoint-on-the-path is the point on the path which represents the point on the path which is [ ‘startOffset’ minus half of the total advance values for all of the glyphs in the ‘textPath’ element ] distance along the path from the start of the path

然后,它说:

When the inline-base direction is horizontal, then any ‘x’ attributes on ‘text’ or ‘tspan’ elements represent new absolute offsets along the path, thus providing explicit new values for startpoint-on-the-path.

换句话说,您的 x="0" 属性将覆盖 startOffsettext-anchor 设置。

因此,就像您在第二个 SVG 中一样,更加简单和明确是可行的方法。