Last active
August 29, 2015 14:07
-
-
Save gordonnl/b477a9f4bdda9effdd12 to your computer and use it in GitHub Desktop.
Return pages of text based on available space
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* 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