SVG 텍스트 상자 너비 계산 및 자동 줄 바꿈 구현하기
SVG에서 텍스트 상자의 실제 렌더링 너비를 알아내거나, 지정한 너비를 초과했을 때 자동으로 줄 바꿈을 적용하려면 getBBox() 함수를 사용하는 것이 가장 확실한 방법입니다.
동작 원리
getBBox()는 텍스트 요소가 화면에 실제로 그려지는 크기(바운딩 박스)를 반환합니다. 이 값을 활용해 텍스트 객체에 단어를 하나씩 순차적으로 추가하면서 매번 너비를 측정하고, 설정한 최대 너비(maxWidth)를 초과하는 순간 줄 바꿈 문자(\n)를 삽입하는 방식입니다.
Raphael.js 구현 예제
var a = Raphael(500, 500);
var b = a.text(100, 100).attr('text-anchor', 'start');
var maxWidth = 100;
var content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec semper mauris. Sed gravida augue feugiat nulla ultrices efficitur. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sit amet lobortis eros, et lobortis diam. Aenean arcu velit, condimentum eu lacus in, dignissim bibendum odio. Mauris ultricies nunc et lorem bibendum dignissim. Ut porttitor purus vitae diam efficitur ultrices. Integer dignissim efficitur lorem, non vehicula diam scelerisque at ";
var words = content.split(" ");
var tempText = "";
for (var i = 0; i < words.length; i++) {
b.attr("text", tempText + " " + words[i]);
if (b.getBBox().width > maxWidth) {
tempText += "\n" + words[i];
} else {
tempText += " " + words[i];
}
}
b.attr("text", tempText.substring(1));
코드 설명
- Raphael(500, 500) : 500×500 크기의 SVG 캔버스(페이퍼)를 생성합니다.
- a.text(100, 100) : 좌표 (100, 100)에 텍스트 객체를 만들고, 정렬 기준을 'start'(왼쪽 정렬)로 지정합니다.
- maxWidth = 100 : 한 줄이 가질 수 있는 최대 너비를 픽셀 단위로 설정합니다.
- content.split(" ") : 전체 문장을 공백 기준으로 나누어 단어 배열을 만듭니다.
- b.getBBox().width : 현재까지 추가된 텍스트의 실제 렌더링 너비를 측정합니다.
- 측정된 너비가 maxWidth를 초과하면 해당 단어 앞에
\n(줄 바꿈)를 붙여 다음 줄로 내립니다. - 마지막에 substring(1)로 맨 앞의 불필요한 공백을 제거한 뒤 최종 텍스트를 적용합니다.
참고 사항
이 방식은 텍스트가 실제로 렌더링된 후에야 정확한 너비를 얻을 수 있으므로, 웹 폰트를 사용하는 경우라면 폰트 로딩이 완료된 시점에 실행하는 것이 좋습니다. 또한 이 원리는 Raphael.js에 국한되지 않으며, 순수 SVG의 getBBox() API를 그대로 활용하기 때문에 D3.js 등 다른 SVG 라이브러리에서도 동일하게 응용할 수 있습니다.