Skip to content

Instantly share code, notes, and snippets.

@gordonnl
Last active August 29, 2015 14:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gordonnl/b477a9f4bdda9effdd12 to your computer and use it in GitHub Desktop.
Save gordonnl/b477a9f4bdda9effdd12 to your computer and use it in GitHub Desktop.
Return pages of text based on available space
/*
*
* Use:
* var textPages = textToPages(myElement)
* returns array of strings.
*
*/
var textToPages = function(element) {
var pages = [];
var availableHeight = element.parentNode.clientHeight;
var lineHeight = parseInt(window.getComputedStyle(element).lineHeight)
var linesMax = Math.floor(availableHeight / lineHeight);
var words = element.innerHTML.split(' ');
var lines = element.clientHeight / lineHeight;
// Using line-height and available height, work out approximately how many
// words to fill a page. More efficient than going one by one.
var approxLength = Math.floor((linesMax / lines) * words.length);
// Our element for injecting content and performing experiments upon.
var test = element.cloneNode(true);
element.parentNode.appendChild(test);
// Add approx content, then either add or remove words until the limit passed.
// Then take away the one that bust the limit and it's as close as possible.
var addPage = function() {
test.innerHTML = words.splice(0, approxLength).join(' ');
var tooSmall = false;
var tooLarge = false;
var word = '';
var cap2 = 0;
do {
cap2 ++;
if (cap2 > 100) {
console.log('Infinite loop avoided.');
break;
}
// If less, add more words
if (test.clientHeight <= availableHeight) {
tooSmall = true;
// If was too large to begin with, upon reaching here,
// one less than limit has been found.
if (tooLarge) break;
// If there are no more words, our work is done.
if (words.length == 0) break;
// Add one word
test.innerHTML += ' ' + words.splice(0, 1);
} else {
tooLarge = true;
// Remove one word
word = test.innerHTML.slice(test.innerHTML.lastIndexOf(' '));
test.innerHTML = test.innerHTML.substring(0, test.innerHTML.lastIndexOf(' '));
// Put word back with remaining
words.unshift(word)
}
// Repeat until both true
} while (!tooSmall || !tooLarge)
pages.push(test.innerHTML);
}
var cap = 0;
do {
cap ++;
if (cap > 100) {
console.log('either there is over 100 pages or something has gone wrong.');
break;
}
addPage();
// Repeat while words remain
} while (words.length > 0);
element.parentNode.removeChild(test);
test = null;
return pages;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment