SVG - создать путь для textpath динамически? - PullRequest
0 голосов
/ 14 января 2019

Я хочу иметь изогнутый текст вдоль пути (полукруга) в SVG. Я следовал этому уроку, и это здорово: https://css -tricks.com / snippets / svg / curved-text-вдоль-пути /

Проблема в том, что представленный там путь работает только для этого конкретного текста - Dangerous Curves Ahead. Если вы оставите только Dangerous слово, вот что произойдет: https://codepen.io/anon/pen/pqqVGa - оно больше не работает (текст больше не распределяется равномерно по пути).

Я хочу, чтобы он работал независимо от длины текста. Как этого добиться?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Используя атрибуты 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>

и создавать анимацию с использованием этого атрибута ( click canvas )

<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>	 
0 голосов
/ 14 января 2019

Предполагается, что начальный размер текста (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>

UPDATE

ОП комментирует:

Спасибо за ответ. Вместо настройки размера шрифта я бы предпочел создать новый путь, который будет длиннее / меньше и соответствует ширине текста. Не уверен, как это сделать. - Feerlay

Пожалуйста, прочитайте комментарии в коде. Исходя из длины текста, я вычисляю новый путь, но я предполагаю много вещей: я предполагаю, что новый путь начинается в той же точке, что и старый.

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...