【问题标题】:Dynamically adapt a text to a path element in an SVG使文本动态适应 SVG 中的路径元素
【发布时间】:2021-05-06 18:35:05
【问题描述】:

我的 SVG 具有不同尺寸的形状,如下所示,我希望我的文本具有适合其相关形状长度的大小(填充而不溢出)。

我尝试了 font-size-adjust 但没有结果,并且 textLength lengthAdjust 使我的文本变形,我应该使用 textPath 和 href 逻辑吗?

感谢您的帮助

<svg viewBox="0 0 220 220">

  <g>
  <path fill="orange" d="M30 110 L 20 110 L 20 20 L 30 10 L 40 20 L 40 110 Z"/>
    <text font-size="1em" transform="rotate(-90, 30, 110)" x="30" y="110" dominant-baseline="middle">Object number 1</text>
  </g>
  
  <g>
  <path fill="red" d="M 50 110 L 40 110 L 40 50 L 50 40 L 60 50 L 60 110 Z"/>
  <text transform="rotate(-90, 50, 110)" x="50" y="110" dominant-baseline="middle">Object number 2</text>
  </g>
  
  <g>
  <path fill="yellow" d="M 80 110 L 60 110 L 60 50 L 80 40 L 100 50 L 100 110 Z"/>
  <text transform="rotate(-90, 80, 110)" x="80" y="110" dominant-baseline="middle">Object number 3</text>
  </g>
  
</svg>

这是我想要获得的效果图:

字母之间的空格是我不想使用 textLength 的原因:

我在这里的渲染是:

【问题讨论】:

  • 你想根据ro的形状改变文字的字体大小,还是根据文字改变形状的高度? (第二个选项似乎更相关)
  • 嗨@michaelRovinsky,我想根据形状长度更改文本的字体大小,我用所需渲染的图片编辑了我的帖子。谢谢
  • 好的,我明白了。还有一点:如果字体大,宽度要窄以包含文本,是否也要调整路径的宽度?为什么首先黄色路径的宽度与橙色和红色路径的宽度不同?
  • 这些是房屋的形状,从数据库中提取不同的尺寸,所以它们的长度和宽度不一样,名字必须适合房子,而不是必须适合的房子文字……就宽度而言,文字也不宜太宽,不过我还没想好。但是,如果我们想走得更远,我想做的事情是:使文本大小尽可能长地填充形状而不突出(长度或宽度)希望这很清楚,谢谢!

标签: svg path font-size viewbox


【解决方案1】:

第一种方法:tou可以设置文本的textLength等于路径的高度。由于您的路径有小费,我选择了 90% 的高度。但是,如果您的路径比文本小得多,则文本将显得拥挤。要理解我的意思,将字体大小更改为 3em

let pthHeight = pth.getBBox().height;

txt.setAttribute("textLength",pthHeight*.9 )
svg{width:50vh}
<svg viewBox="0 0 50 120">
  <path fill="orange" id="pth" d="M30 110 L 20 110 L 20 20 L 30 10 L 40 20 L 40 110 Z"/>
    <text  id="txt" font-size="1em" transform="rotate(-90, 30, 110)" x="30" y="110" dominant-baseline="middle" lengthAdjust="spacingAndGlyphs">Object number 1</text>  
</svg>

另一种解决方案是在 while 循环中更改字体大小,直到文本长度小于路径的高度。这假设文本的初始长度比高度更长。

let pthHeight = pth.getBBox().height;

function setFontSize(txt){
  let fs = txt.getAttribute("font-size");
  let textLength = txt.getComputedTextLength();
  let fontSize = txt.getAttribute("font-size");
  while(textLength > pthHeight){
    fontSize -= 1;
    txt.setAttribute("font-size",fontSize);
    textLength = txt.getComputedTextLength();
  }
}


setFontSize(txt)
svg{width:50vh}
<svg viewBox="0 0 50 120">
  <path fill="orange" id="pth"  d="M30 110 L 20 110 L 20 20 L 30 10 L 40 20 L 40 110 Z"/>
    <text id="txt" font-size="16" transform="rotate(-90, 30, 110)" x="30" y="110" dominant-baseline="middle" >Object number 1</text>  
</svg>

【讨论】:

  • 宽度也应该检查(见@PeiKobayashi的最后评论):while(textLength &gt; pthHeight || textWidth &gt; pthWidth)
  • 有趣!但是在第一种情况下,文本会像您说的那样被拉伸或塞满,但我想修改完整的字体大小(示例如下)link第二种方法应该更合适,但我不能调用这个函数对于我所有的元素(这是一个巨大的 SVG,有很多房子......)
  • 请编辑您的问题并添加新图像。至于许多房屋,您可以循环包含每个路径和文本的组
猜你喜欢
  • 2019-06-08
  • 2023-03-03
  • 2021-12-01
  • 2015-04-23
  • 1970-01-01
  • 2022-01-12
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多