如何使用tref元素重用SVG文本

如果看完了还不过瘾?想和作者深聊相关话题,可以点击这里向作者提问!

写一次SVG代码,然后在多个地方重用,可以帮助你写出更多模块化的代码,而且它也有助于维护。通过tref元素,SVG可以很方便地重用text元素的内容。

上周我大概讲解了tspan元素,并通过几个实例讲了如何使用它来单独给文本添加样式和定位。几个示例中都使用了位置属性——xydxdy,还提到了其它几个属性。

我们现在来讲讲剩下的两个属性,然后再讲讲使用tref元素重用SVG文本。不过注意tref元素是SVG 1.1规范的一部分,它已经从SVG 2.0规范中删除了。我在这里介绍它,也许哪天你就碰到它了呢。

textLengthlengthAdjust属性

还有两个属性是textLengthlengthAdjust,这两个属性都可以直接添加给任何tspan元素。

我们先创建一个SVG元素,定义视窗的尺寸,然后给它添加样式,这样我们可以看到视窗的边框以及渲染到视窗之外的内容,字号加大。

<svg width="660" height="220" style="outline: 1px solid red; font-size: 2em; overflow: visible;">  
  <text textLength="400" lengthAdjust="spacingAndGlyphs">  
    <tspan x="280" y="80">SVG 1</tspan>  
    <tspan x="280" dy="36" fill="red">SVG 2</tspan>  
  </text>  
</svg>

我把两个tspan上下放置,给第二个tspan加一个红色填充。我还给<text>元素添加了textLengthlengthAdjust属性。然而,文本没有拉伸。

SVG 1SVG 2

但是,给第一个tspan添加了这两个属性之后,它确实拉伸了间隔、还有字形,如下图所示。

<svg width="660" height="220" style="outline: 1px solid red; font-size: 2em; overflow: visible;">  
  <text x="280" y="40">  
    <tspan x="280" y="80" textLength="400" lengthAdjust="spacingAndGlyphs">SVG 1</tspan>  
    <tspan x="280" dy="36" fill="red">SVG 2</tspan>  
  </text>  
</svg>
SVG 1SVG 2

这是为什么呢?他们和rotate属性不一样,给text元素设置的textLengthlengthAdjust,不会扩散到tspan

这是一个例外,我发现如果你给text元素添加textLengthlengthAdjust属性,然后没有给第一个tspan设置xy的值,那么textLengthlengthAdjust也有可能会被继承。

我不确定这是bug,还是预期的行为,但是我还是在这里提出来说一下,以防你之后碰到,然后纠结为什么。

<svg width="660" height="220" style="outline: 1px solid red; font-size: 2em; overflow: visible;">  
  <text x="280" y="80" textLength="400" lengthAdjust="spacingAndGlyphs">hello  
    <tspan>SVG 1</tspan>  
    <tspan x="280" dy="36" fill="red">SVG 2</tspan>  
  </text>  
</svg>

在这个示例中我直接给text元素添加了hello文本,在第一个tspan之前,我直接给text元素添加了这两个属性。我还给text元素加了定位,但是我没有给第一个tspan添加任何xy坐标,所以它定位在hello文本之后。

hello这个单词被拉伸了,因为它是text中的内容,但是第一个tspan中的内容“SVG 1”也被拉伸了。也就是说设置textLengthlengthAdjust会拉伸它们被应用的直线上(同一水平线),而不考虑它们是设置在哪个元素之上。

helloSVG 1SVG 2

如果你把第二个tspan元素的定位坐标删除,它也会成为被拉伸的元素之一,因为它也和前两个元素统一了战线。

helloSVG 1SVG 2

不过我还是不确定这是否是预期的行为,或者是bug,或者是我写错了什么,在这里指出欢迎大家拍砖。

tref元素

注意:tref元素是SVG 1.1规范的内容,但是它已经从SVG 2.0规范中删除了。也就是说在你看到这篇文章的时候,可能它已经不工作了。所以这里使用图片来展示实例的结果

早在之前SVG系列的文章中,我说了可以在一个位置定义SVG代码,然后在SVG文件的其它部分重用。

tref元素也是一样的。它允许你在一个<defs>元素中定义引用文本,然后在后面引用它。如果你不了解<defs>的话,我建议你回去看看之前的文章

或者你可以看看我前面创建<text>元素时候的示例,我在<defs>标签中定义了<text>元素。注意我给<text>元素添加了一个id,为referenced

当你想要显示文本的时候,在<tref>元素中使用xlink:href属性引用就可以啦。

<svg width="660" height="220" style="outline: 1px solid red; font-size: 2em; overflow: visible;">  
  <defs>  
    <text id="referenced">SVG 1</text>  
  </defs>

  <text>  
    <tspan x="280" y="80">  
      <tref xlink:href="#referenced"/>  
    </tspan>  
    <tspan x="280" dy="36" fill="red">SVG 2</tspan>  
  </text>  
</svg>

这里我在一个tref元素中引用了“SVG 1”的文本,而“SVG 2”放置在一个tspan中,放在“SVG 1”下面。

SVG文本

还有更高效的方法,设置defs来包含文本“SVG”,然后在第二个和第二个tspan中再额外加上数字12

<svg width="660" height="220" style="outline: 1px solid red; font-size: 2em; overflow: visible;">  
  <defs>  
    <text id="referenced-2">SVG</text>  
  </defs>

  <text>  
    <tspan x="280" y="80">  
      <tref xlink:href="#referenced-2"/> 1  
    </tspan>  
    <tspan x="280" dy="36" fill="red">  
      <tref xlink:href="#referenced-2"/> 2  
    </tspan>  
  </text>  
</svg>

这里我在每个tspan中加上了12,但是SVG这个文本就是作为一个引用放进去的。我还把id改成了referenced-2,这样它就不会和前面的示例混淆了。

SVG文本

在这些示例中,我把tref放进了tspan中,tref还可以直接放在text元素中。引用的文本可以出现在任何tref元素出现的地方。

总结思考

如果你知道如何使用<defs>,以及如何重用SVG代码。我想你学习<tref>元素应该不会有任何困难的。

你可以在<defs>标签中定义你想要重用的文本,然后在<tref>元素中使用xlink:href来引用文本。解释比较麻烦,直接使用比较容易理解。

关于SVG文本还有很多内容。接下来的两周,我将讲讲关于SVG支持的文本布局特性,以及向你展示一些可以在水平和垂直方向排列对齐SVG文本的属性。

本文根据@Steven Bradley的《How To Reuse SVG Text With The tref Element》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://vanseodesign.com/web-design/svg-text-tref-element/

彦子

在校学生,本科计算机专业。逗比一枚,热爱前端热爱生活,喜欢CSS喜欢JavaScript喜欢SVG,爱玩PS玩AI玩啊逗比的软件。努力向上,厚积薄发。

如需转载,烦请注明出处:http://www.w3cplus.com/svg/svg-text-tref-element.html

如需转载,烦请注明出处:https://www.w3cplus.com/svg/svg-text-tref-element.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部