Search code examples
javascriptjquerygoogle-closure-library

Number of characters displayed per line


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:

  1. Divide rectX to FONT_SIZE to get the number of characters displayed per line.
  2. 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);

};

Solution

  • I think your problem might be that font-size=13px doesn't mean it use 13px to display. It use around 8px in my browser (latest chrome on win7). So, I create a script to detect an actual font-size from span then calculate it to fit the paragraphs.

    See example here : http://jsfiddle.net/LNrgc/3/ enter image description here