Measuring text height using DOM objects
Written by Richard Heyes, RGraph author, on 1st May 2013
Measuring the width of canvas
text is simple to do by using the context.measureText()
function. This function however only provides you with the width
of the text - not the height
. Normally this isn't so bad - except when you absolutely need the height
- it's not available. Fortunately, this can be solved by using the below function. This function takes the text, whether it's
bold or not, the font and the point size (eg 12pt
= 12
) and adds it to a dynamically generated div
that's positioned off-screen.
This div
can then be measured using the offsetWidth
and the offsetHeight
properties of the div
and these measurements can then be used as the dimensions of the text.
A point worthy of note is that adding elements to the dom
has a cost - and in some browsers this can slow down an animation quite significantly.
So for this reason the function uses a cache so that it doesn't repeatedly measure the same thing over and over again. This
method of measuring the text height is used in RGraph to good effect when displaying multi-line text.
// // Measures text by creating a DIV in the document and adding the relevant text to it. // Then checking the offsetWidth and offsetHeight. Because adding elements to the DOM is not particularly // efficient in animations (particularly) it caches the resulting width and height. // // @param string text The text to measure // @param bool bold Whether the text is bold or not // @param string font The font to use // @param size number The size of the text (in pts) // @return array A two element array of the width and height of the text // function MeasureText(text, bold, font, size) { // This is used to cache repeated calls with the same arguments var str = text + ':' + bold + ':' + font + ':' + size; if (typeof arguments.callee.cache === 'object' && arguments.callee.cache[str]) { return arguments.callee.cache[str]; } var div = document.createElement('DIV'); div.innerHTML = text; div.style.position = 'absolute'; div.style.top = '-100px'; div.style.left = '-100px'; div.style.lineHeight = size * 1.5 + 'px'; div.style.fontFamily = font; div.style.fontWeight = bold ? 'bold' : 'normal'; div.style.fontSize = size + 'pt'; document.body.appendChild(div); var size = [div.offsetWidth, div.offsetHeight]; document.body.removeChild(div); // Add the sizes to the cache as adding DOM elements is costly and can cause slow downs if (typeof arguments.callee.cache != 'object') { arguments.callee.cache = []; } arguments.callee.cache[str] = size; return size; }