Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How to either determine SVG text box width or force line breaks after 'x' characters?
When working with SVG text elements, you often need to control text wrapping since SVG doesn't automatically wrap text like HTML. This tutorial shows how to measure text width using getBBox() and implement word wrapping.
The Problem
SVG text elements don't wrap automatically. Long text will extend beyond boundaries, requiring manual line breaks based on width measurements.
Using getBBox() for Text Measurement
The getBBox() method returns the bounding box dimensions of SVG elements, including text width and height.
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.3.0/raphael.min.js"></script>
</head>
<body>
<div id="canvas"></div>
<script>
var paper = Raphael("canvas", 500, 300);
var textElement = paper.text(50, 50, "Sample text").attr({
'text-anchor': 'start',
'font-size': 14
});
// Get text dimensions
var bbox = textElement.getBBox();
console.log("Text width:", bbox.width);
console.log("Text height:", bbox.height);
// Draw a rectangle around the text to visualize bounds
paper.rect(bbox.x, bbox.y, bbox.width, bbox.height).attr({
'fill': 'none',
'stroke': 'red'
});
</script>
</body>
</html>
Implementing Word Wrapping
Here's how to wrap text by adding words one at a time and checking width:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.3.0/raphael.min.js"></script>
</head>
<body>
<div id="wrap-canvas"></div>
<script>
var paper = Raphael("wrap-canvas", 400, 200);
var textElement = paper.text(20, 20).attr({
'text-anchor': 'start',
'font-size': 14
});
var maxWidth = 300;
var content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec semper mauris. Sed gravida augue feugiat nulla ultrices efficitur.";
var words = content.split(" ");
var tempText = "";
for (var i = 0; i < words.length; i++) {
// Test adding the next word
var testText = tempText + (tempText ? " " : "") + words[i];
textElement.attr("text", testText);
if (textElement.getBBox().width > maxWidth && tempText) {
// Too wide, add line break
tempText += "<br>" + words[i];
} else {
// Fits on current line
tempText = testText;
}
}
textElement.attr("text", tempText);
// Draw boundary box to show max width
paper.rect(20, 20, maxWidth, textElement.getBBox().height).attr({
'fill': 'none',
'stroke': 'blue',
'stroke-dasharray': '5,5'
});
</script>
</body>
</html>
Alternative: Character-Based Line Breaks
For simpler cases, you can force line breaks after a specific number of characters:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.3.0/raphael.min.js"></script>
</head>
<body>
<div id="char-canvas"></div>
<script>
function wrapTextByCharacters(text, maxChars) {
var result = "";
for (var i = 0; i < text.length; i += maxChars) {
result += text.substring(i, i + maxChars);
if (i + maxChars < text.length) {
result += "<br>";
}
}
return result;
}
var paper = Raphael("char-canvas", 400, 150);
var longText = "This is a very long text that needs to be wrapped at specific character intervals.";
var wrappedText = wrapTextByCharacters(longText, 25);
paper.text(20, 50, wrappedText).attr({
'text-anchor': 'start',
'font-size': 14
});
</script>
</body>
</html>
Comparison of Methods
| Method | Accuracy | Performance | Use Case |
|---|---|---|---|
| getBBox() word wrapping | High | Slower | Precise width control |
| Character-based breaking | Medium | Fast | Simple fixed-width layouts |
Key Points
-
getBBox()returns accurate dimensions after text is rendered - Test text width before committing to avoid overflow
- Handle edge cases like single words longer than max width
- Character-based wrapping works for monospace fonts
Conclusion
Use getBBox() for precise SVG text wrapping based on actual rendered width. For simpler cases, character-based line breaks offer a faster alternative with acceptable results.
