SVG의 textPath 요소에 텍스트 균등 배치 정보
SVG에서는 text 요소에 textLength 속성을 설정하여 문자 간격을 조정할 수 있습니다.
textLength 의 값은 텍스트의 폭을 나타내고 텍스트가 거기에 맞추어 자동적으로 배치되기 때문에… … 아마.
<svg width="600" height="400" xmlns="http://www.w3.org/2000/svg">
<text x="0" y="20">
This is a pen.
</text>
<text x="0" y="60" textLength="300">
This is a pen.
</text>
</svg>
text 요소는 textPath 요소와 결합하여 경로를 따라 텍스트를 배치 할 수 있습니다.
<svg width="600" height="400" xmlns="http://www.w3.org/2000/svg">
<path d="M 30 160 Q 150 0 300 160" stroke="black" fill="none" id="path1"></path>
<text>
<textPath href="#path1">This is a pen.</textPath>
</text>
</svg>
이 주제는 경로를 사용할 때 문자 간격을 조정하는 방법입니다.
보통으로 생각해 text 요소의 textLength 속성을 사용하면 좋다고 생각하지만, 무려 textPath 요소에도 textLength가 있다.
어느 쪽을 사용하면 좋을지 모르겠다.
몰라서 시험해 보았다.
<svg width="600" height="400" xmlns="http://www.w3.org/2000/svg" style="font-family: Times New Roman;font-size: 14px;">
<g>
<path d="M 30 160 Q 150 0 300 160" stroke="black" fill="none" id="path1"></path>
<text>
<textPath href="#path1">This is a pen.</textPath>
</text>
</g>
<g>
<path d="M 30 200 Q 150 40 300 200" stroke="black" fill="none" id="path2"></path>
<text textLength="300">
<textPath href="#path2">This is a pen.</textPath>
</text>
</g>
<g>
<path d="M 30 240 Q 150 80 300 240" stroke="black" fill="none" id="path3"></path>
<text>
<textPath href="#path3" textLength="300">This is a pen.</textPath>
</text>
</g>
<g>
<path d="M 30 280 Q 150 120 300 280" stroke="black" fill="none" id="path4"></path>
<text textLength="300">
<textPath href="#path4" textLength="300">This is a pen.</textPath>
</text>
</g>
<g>
<path d="M 30 320 Q 150 160 300 320" stroke="black" fill="none" id="path5"></path>
<text textLength="150">
<textPath href="#path5" textLength="300">This is a pen.</textPath>
</text>
</g>
</svg>
실행 결과
Firefox에서는 text 요소의 textLength 속성의 값이 사용된다.
Chrome에서는 textPath 요소의 textLength 속성의 값이 사용된다.
그래서 Firefox와 Chrome에서 외형을 맞추고 싶다면 두 속성에 같은 값을 설정하면 좋을 것 같다.
문제는 Edge이다. 어느 쪽의 값도 사용되지 않는지 무엇 하나 외형이 변하지 않는다. 동기가 느껴지지 않는다.
3개의 브라우저 사이에서 외형을 가지려면 textLength에서는 안 된다.
원래 SVG에 자세하지 않기 때문에 패스상의 균등 배치에 textLength를 사용하는 것이 진정한 방법인지도 모른다.
textLength 이외에도 문자간의 간격을 설정하는 방법이 있다.
그것은 text 요소의 letter-spacing 속성. 이름 그대로 문자간의 간격치를 나타내고 있다.
균등 배치가 목적이기 때문에 먼저 이쪽을 시도하면 좋았다…
<svg width="600" height="400" xmlns="http://www.w3.org/2000/svg" style="font-family: Times New Roman;font-size: 14px;">
<g>
<path d="M 30 160 Q 150 0 300 160" stroke="black" fill="none" id="path1"></path>
<text letter-spacing="20">
<textPath href="#path1">This is a pen.</textPath>
</text>
</g>
</svg>
저기를 세우면 이쪽이 서지 않고. 사이좋게 할 생각이 없는 세 사람이다.
그렇다면 textLength와 조합해 보자.
<svg width="600" height="400" xmlns="http://www.w3.org/2000/svg" style="font-family: Times New Roman;font-size: 14px;">
<g>
<path d="M 30 160 Q 150 0 300 160" stroke="black" fill="none" id="path1"></path>
<text letter-spacing="20">
<textPath href="#path1">This is a pen.</textPath>
</text>
</g>
<g>
<path d="M 30 200 Q 150 40 300 200" stroke="black" fill="none" id="path2"></path>
<text textLength="150" letter-spacing="20">
<textPath href="#path2">This is a pen.</textPath>
</text>
</g>
<g>
<path d="M 30 240 Q 150 80 300 240" stroke="black" fill="none" id="path3"></path>
<text letter-spacing="20">
<textPath href="#path3" textLength="250">This is a pen.</textPath>
</text>
</g>
<g>
<path d="M 30 280 Q 150 120 300 280" stroke="black" fill="none" id="path4"></path>
<text textLength="150" letter-spacing="20">
<textPath href="#path4" textLength="250">This is a pen.</textPath>
</text>
</g>
</svg>
실행 결과
대답이 보였다. 각 브라우저에서의 속성의 채용 규칙은 다음과 같이 된다고 생각된다.
(◎: 최우선, ○: 우선, ×: 사용되지 않음)
- Firefox : ○text.textLength ×textPath.textLength ×text.letter-spacing
- Chrome : ×text.textLength ◎textPath.textLength ○text.letter-spacing
- Edge : ×text.textLength ×textPath.textLength ○text.letter-spacing
간단히 말해서, 그려야 할 문자열의 간격이 w이고 그 간격으로 그릴 때 문자열의 폭이 y이면
text 요소와 textPath 요소의 textLength 속성에 y를, text 요소의 letter-spacing 속성에 w를 설정하면
3개의 브라우저상에서 외형이 갖추어져야 한다.
이번은 y=300에 고정하고 있지만, 그 경우의 w는 무엇일까?
조금 움직여 보았는데, letter-spacing이 설정되어 있지 않을 때는 letter-spacing=0이 되는 것 같다.
그렇다면 letter-spacing 및 textLength 속성이 설정되지 않은 경우 문자열의 너비를 계산할 수 있다면
y와의 차이로부터 w의 값을 계산할 수 있을 것 같다.
다음 코드는 X를 계산하는 코드입니다.
const textLength = 300;
const svgText = document.getElementById('text1');
const svgTextPath = document.getElementById('textPath1');
//letter-spacing=0のときのテキストの幅
const box = svgText.getBBox();
//元々のテキストの幅とtextLengthのギャップ
const diff = textLength - box.width;
//テキストの長さ
const number = svgTextPath.textContent.length;
//文字間の隙間の数はテキスト長-1だからギャップ/テキスト長-1で割れば大丈夫だろう…
const w = diff / (number - 1);
//Edge用属性
svgText.setAttribute("letter-spacing", `${w}`);
//Firefox用属性
svgText.setAttribute("textLength", `${textLength}`);
//Chrome用属性
svgTextPath.setAttribute("textLength", `${textLength}`);
실행 결과
좋은 느낌으로 외형이 갖추어졌다. Firefox와 Chrome에서 조금 어긋난다고 생각하지 말라.
그렇다고 해도 2018년도 되어 이런 사양의 차이에 사고팔고하는 것은 어떤 것일까?
어쩌면 더 간단하고 합당한 방법이 있을지도. 아니, 원해.
이상입니다.
Reference
이 문제에 관하여(SVG의 textPath 요소에 텍스트 균등 배치 정보), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/MKLemma/items/c38cd2587a1451a95e3e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)