Is there any way to figure out the number of characters a browser will display per line inside a container of known size?
So I have a rectangle of known dimensions, recX
and recY
, a pre-defined FONT_SIZE
of 13
.
I am trying to compute the height of a paragraph like this:
- Divide
rectX
toFONT_SIZE
to get the number of characters displayed per line. - Divide the length of the paragraph(number of characters) to the width to get the number of rows it has and then multiply that by the
FONT_SIZE
to get it's display height.
The problem is that for my 650px in width container(test case), the result of 650 / 13 is 50, but the browser displays about 100 something characters per line, it doesn't stick to any default. I am using font-family:Lucida Console Monospace 13px, line-height:1em
.
The Code
var width = Math.floor(this.articleSize.width / this.FONT_SIZE);
// this.article.paragraphs is an array of paragraphs without <p> or </p>.
for (var i = 0, ii = this.article.paragraphs.length; i < ii; i++) {
// based on the above compute the height/number of rows for each paragraph.
// This is a basic matrix approach.
// For those of you not familiar with the Closure Library, the goog.math.Size obj
// is a (width, height) object.
this.article.sizes[i] = new goog.math.Size(width, Math.ceil(this.article.paragraphs[i].length / width * this.FONT_SIZE));
};
var i = 0, currentPage = 0, pg = [], height = this.articleSize.height - 20, ii = this.article.paragraphs.length;
while (i < ii) {
// So here based on the height I am trying to see how many paragraphs
// Can fit into one 'page'. The navigation is horizontal, with a book like
// animation.
if((height - this.article.sizes[i].height) > 0) {
pg.push('<p>' + this.article.paragraphs[i] + '</p>');
height -= this.article.sizes[i].height;
i++;
} else {
this.article.pages[currentPage] = pg;
currentPage++;
pg = [];
height = this.articleSize.height - 20;
};
};
This has to work on any resolution/viewport size, which means the pages are computed at runtime and the entire process is done again on every resize which differs from the current size with more than 50 pixels in any way.
HERE IS THE WORKAROUND
project.MainArticle.loader.prototype.divideText = function(articleText) {
articleText = goog.string.collapseWhitespace(articleText);
articleText = articleText.replace(/<p><\/p>|• Comments will be turned on later/g, '').replace(/<p>\.<\/p>/g, '');
var trick = articleText.replace(/<p>/g, '<p class = \'trick-p\'>');
this.articleTextContainer.innerHTML = trick;
this.preAppendedParagraphs = goog.dom.getElementsByClass('trick-p');
for(var i = 0, ii = this.preAppendedParagraphs.length; i < ii; i++) {
this.article.sizes.push(+(this.preAppendedParagraphs[i]['offsetHeight'] + 10));
};
this.articleTextContainer.innerHTML = '';
this.article.paragraphs = articleText.replace(/<p>/g, '').split('</p>');
};
/**
* Divide the text into pages
* @private
*/
project.loader.prototype.createPages_ = function() {
var i = 0, currentPage = 0, pg = [], height = this.articleSize.height, ii = this.article.paragraphs.length - 1;
while(i < ii) {
if((height - this.article.sizes[i]) >= 0) {
pg.push('<p class=\'nz-ma-txt-p\'>' + this.article.paragraphs[i] + '</p>');
height -= this.article.sizes[i];
i++;
} else {
this.article.pages[currentPage] = pg;
currentPage++;
pg = [];
height = this.articleSize.height;
};
};
console.log(this.article);
};