Skip to content

Instantly share code, notes, and snippets.

@JordanForeman
Created January 20, 2016 22:16
Show Gist options
  • Select an option

  • Save JordanForeman/70bd1c5c520983be7144 to your computer and use it in GitHub Desktop.

Select an option

Save JordanForeman/70bd1c5c520983be7144 to your computer and use it in GitHub Desktop.
/**
* Measures a canvas and splits lines of text so that they fit within the width thereof.
* Requires some text styling to be applied to the canvasContext already, and will not function as expected if that is changed between calculation and drawing of returned lines
*
* @param canvas - <canvas>
* @param text - String the text to measure and break up
* @param padding - the horizontal padding to take into account (assumes left/right padding are equivalent)
*
* @returns [Array] - an array containing lines of text that, when rendered on the canvas will not exceed the canvas' width
*/
function fragmentText(canvas, text, padding) {
var maxWidth = canvas.width - (padding*2),
context = canvas.getContext('2d'),
lines = [],
words = text.split(' ');
// Whoops - something went terribly wrong
if (maxWidth === NaN) return [text];
// We'll be constantly removing words from our words array to build our lines. Once we're out of words, we can stop
while (words.length) {
var tmp = words[0]; // Capture the current word, in case we need to re-add it to array
var line = words.shift(); // Start our line with the first word available to us
// Now we'll continue adding words to our line until we've exceeded our budget
while ( words.length && context.measureText(line).width < maxWidth) {
tmp = words[0];
line = line + " " + words.shift();
}
// If the line is too long, remove the last word and replace it in words array.
// This will happen on all but the last line, as we anticipate exceeding the length to break out of our second while loop
if (context.measureText(line).width > maxWidth) {
line = line.substring(0, line.lastIndexOf(' '));
words.unshift(tmp);
}
// Push the finshed line into the array
lines.push(line);
}
return lines;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment