最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Size of character in pixels - Stack Overflow

programmeradmin2浏览0评论

I am trying to create text box in the HTML5 canvas, I know you can't actually do this, so I am creating a box and creating some text at the same location. But, I want to make sure the text stays in the box so I need to know when part of the text is extending out of the box. I figure I should be able to measure the text in terms of pixels and then pare it to the box. My question is, using javascript, how can I measure the size of the characters for any given font?

I am trying to create text box in the HTML5 canvas, I know you can't actually do this, so I am creating a box and creating some text at the same location. But, I want to make sure the text stays in the box so I need to know when part of the text is extending out of the box. I figure I should be able to measure the text in terms of pixels and then pare it to the box. My question is, using javascript, how can I measure the size of the characters for any given font?

Share Improve this question asked Jan 3, 2014 at 21:20 EasilyBaffledEasilyBaffled 3,88210 gold badges55 silver badges92 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

You can use context.measureText to get the width of your specified text:

// set the font

context.font = "14px verdana";

// use measureText to get the text width

var textWidth = context.measureText("Measure this!").width;

Text wrap would look something like this:

function wrapText(context, text, x, y, maxWidth, fontSizeFace) {
  var words = text.split(' ');
  var line = '';
  var lineHeight=measureTextHeight(fontSizeFace);

  for(var n = 0; n < words.length; n++) {
    var testLine = line + words[n] + ' ';
    var metrics = context.measureText(testLine);
    var testWidth = metrics.width;
    if(testWidth > maxWidth) {
      context.fillText(line, x, y);
      line = words[n] + ' ';
      y += lineHeight;
    }
    else {
      line = testLine;
    }
  }
  context.fillText(line, x, y);
}

You can use as markE mention in his answer the measureText() function.

The specifications defines its result (a TextMetrix):

interface TextMetrics {
  // x-direction
  readonly attribute double width; // advance width
  readonly attribute double actualBoundingBoxLeft;
  readonly attribute double actualBoundingBoxRight;

  // y-direction
  readonly attribute double fontBoundingBoxAscent;
  readonly attribute double fontBoundingBoxDescent;
  readonly attribute double actualBoundingBoxAscent;
  readonly attribute double actualBoundingBoxDescent;
  readonly attribute double emHeightAscent;
  readonly attribute double emHeightDescent;
  readonly attribute double hangingBaseline;
  readonly attribute double alphabeticBaseline;
  readonly attribute double ideographicBaseline;
};

The problem however is that only width is implemented in the major browsers so you cannot get the height (ascent + descent) with this function yet (and I wouldn't be surprised if a canvas based word processor from at least one of the "major 3" shows up right before this gets fully implemented... but that's a regression and a speculation :-) ).

In order to measure the font you will have to use a DOM element, and this little trick will allow you to measure a font's width and height:

Online demo here (open console to see result).

function measureText(font, txt) {

    var el = document.createElement('div'),
        cs, res;

    el.style.cssText = 'position:fixed;left:-4000px;top:-4000px;padding:0;margin:0;font:' + font;
    el.innerHTML = txt;

    document.body.appendChild(el);

    cs = getComputedStyle(el);

    res = {width: cs.getPropertyValue('width'),
           height: cs.getPropertyValue('height')};

    document.body.removeChild(el);

    return res;    
}

The function creates a div element, applies some basic styles to it to place it outside window. This is because we have to attach it to the DOM tree in order to use getComputedStyle() - we also have to get the property values before we remove the element again.

Pass arguments for font as you would with the context (ie. 20px sans-serif) and the text.

It es with a small performance penalty obviously (though using fixed positioned elements won't cause any re-flow so it's not so bad) so use sparsely.

发布评论

评论列表(0)

  1. 暂无评论