【问题标题】:SVG - create path for textpath dynamically?SVG - 动态创建文本路径的路径?
【发布时间】:2019-06-08 04:17:35
【问题描述】:

我想在 SVG 中沿路径(半圆)制作弯曲文本。我已经按照这个教程做了,很棒:https://css-tricks.com/snippets/svg/curved-text-along-path/

问题在于此处显示的路径仅适用于此特定文本 - Dangerous Curves Ahead。如果您只留下 Dangerous 字样,则会发生这种情况:https://codepen.io/anon/pen/pqqVGa - 它不再起作用(文本不再均匀地分布在路径上)。

无论文本长度如何,我都希望它能够正常工作。如何实现?

【问题讨论】:

  • 在原始示例中,文本也没有均匀地分布在路径上,只是字体和字数与路径长度非常匹配。如果您编写了一些 javascript 代码来执行此操作,则可以增加字体大小直到它与路径长度匹配。

标签: svg text


【解决方案1】:

使用lengthAdjust和textLength属性可以调整文字的长度和字母的高度,从而将所需长度的文字放在固定长度的段上

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"  width="500" height="300" viewBox="0 0 500 300">  

<path id="path1" fill="none" stroke="black" d="M30,151 Q215,21 443,152 " /> 

<text id="txt1" lengthAdjust="spacingAndGlyphs" textLength="400" font-size="24">
<textPath id="result" method="align" spacing="auto" startOffset="1%" xlink:href="#path1">
<tspan dy="-10"> very long text very long text very long text </tspan>

</textPath>
</text>
	
</svg>

使用属性startOffset =" 10% "可以调整词组首字符的位置

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"  width="500" height="300" viewBox="0 0 500 300" >  

<path id="path1" fill="none" stroke="black" d="M30,151 Q215,21 443,152 " /> 

<text id="txt1" lengthAdjust="spacingAndGlyphs" textLength="400" font-size="24">
<textPath id="result" method="align" spacing="auto" startOffset="15%" xlink:href="#path1">
<tspan dy="-10"> very long text very long text very long text </tspan>

</textPath>
</text>
	
</svg>

并使用此属性制作动画(点击画布)

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"  width="500" height="300" viewBox="0 0 500 300">  

<path id="path1" fill="none" stroke="black" d="M30,151 Q215,21 443,152 " /> 

<text id="txt1" lengthAdjust="spacingAndGlyphs" textLength="200" font-size="24">
 <textPath id="result" method="align" spacing="auto" startOffset="-100%" xlink:href="#path1">
    <tspan dy="-10"> Very long text Very long text Very long text </tspan>
  <animate
   begin="svg1.click"
   dur="15s"
   attributeName="startOffset"
   values="-100%;1%;1%;100%;1%;1%;-100%"
   repeatCount="5"/> 
 </textPath>
</text>
 
  <text x="200" y="150" font-size="24" fill="orange" >Click me </text>
	
</svg>	 

【讨论】:

【解决方案2】:

这是假设初始文本大小 (35) 太小。

let curveLength = curve.getTotalLength();
let fs = 35;//the initial font size
test.setAttributeNS(null, "style", `font-size:${fs}px`)
while(test.getComputedTextLength() < curveLength){
  fs++
  test.setAttributeNS(null, "style", `font-size:${fs}px`)
}
body {
  background-color: #333;
}

text {
  fill: #FF9800;
}
<svg viewBox="0 0 500 500">
    <path id="curve" d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97" />
    <text id="test">
      <textPath xlink:href="#curve">
        Dangerous
      </textPath>
      </text>
  </svg>

更新

OP 正在评论:

感谢您的回复。我宁愿创建一个更长/更小并与文本宽度匹配的新路径,而不是调整字体大小。不知道该怎么做。 - 费布

请阅读代码中的 cmets。在文本长度的基础上,我正在计算新路径,但我假设了很多事情:我假设新路径与旧路径在同一点开始。

let textLength = test.getComputedTextLength();
// the center of the black circle
let c = {x:250,y:266}
// radius of the black circle
let r = 211;
// the black arc starts at point p1
let p1 = {x:73.2,y:150}
// the black arc ends at point p2
let p2 = {x:426.8,y:150}
// distance between p1 and p2
let d = dist(p1, p2);
// the angle of the are begining at p1 and ending at p2
let angle = Math.asin(.5*d/r);

// the radius of the new circle
let newR = textLength / angle; 
// the distance between p1 and the new p2
let newD = 2 * Math.sin(angle/2) * newR;
// the new attribute c for the path #curve
let D = `M${p1.x},${p1.y} A`
D += `${newR}, ${newR} 0 0 1 ${p1.x + newD},${p1.y} `
document.querySelector("#curve").setAttributeNS(null,"d",D);
// a function to calculate the distance between two points
function dist(p1, p2) {
  let dx = p2.x - p1.x;
  let dy = p2.y - p1.y;
  return Math.sqrt(dx * dx + dy * dy);
}
body {
  background-color: #333;
}

text {
  fill: #FF9800;
}; 
<svg viewBox="0 0 500 500">
    <path id="black_circle" d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97" />
  
  <path id ="curve"  d="M73.2,150 A 211,211 0 0 1 426.8,150" fill="#777" />
    <text id="test">
      <textPath xlink:href="#curve">
        Dangerous curves
      </textPath>
      </text>

  
  </svg>

【讨论】:

  • 感谢您的回复。我宁愿创建一个更长/更小并与文本宽度匹配的新路径,而不是调整字体大小。不知道该怎么做。
  • 再次感谢您 - 这真的很有帮助!看来你数学不错:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
  • 2012-11-22
  • 2019-10-18
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多