Try this, it’s a kind of brute-force approach (it tries every possible line length and chooses the one that has the least difference in line-lengths), but it works:
You will have to manually input the ideal maxWidth-value though, as that depends on the font used and the width of the box.
If the value is too high, then the text-box will also wrapping, and we don’t want that.
But you might not even need to use text-boxes using this approach ?
var txt = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam rutrum sapien ultrices sapien condimentum, et congue risus placerat.";
maxWidth = 110;
minWidth = 30;
var results=[];
for (i=maxWidth; i>=minWidth; i--) {
const splitter = new RegExp('(.{'+i+'}[^ ]* )', 'g');
const newTxt = txt.replace(splitter, '$1\n');
const lines = newTxt.split('\n');
const lineLengths = lines.map(a=> a.length);
results[i] = {
index: i,
txt: newTxt,
lines: lines.length,
contrast: Math.max.apply(Math, lineLengths) - Math.min.apply(Math, lineLengths)
}
}
// best match has the lowest contrast (diff betweens longest and shortest line) and the lowest amount of lines
results.reduce( (acc, curr) => ((curr.contrast < acc.contrast) && (curr.lines<=acc.lines)) ? curr : acc , results[maxWidth]).txt;
One Last thing: if there are line-breaks in the input-text already, then it won’t work as expected. You might want to first filter them out.