There are a couple of ways to slice up this cat. Two obvious ones come readily to mind.
Out-of-view Ruler Technique
This one's the easiest. Just create a text element outside of the canvas's viewBox, populate it with your font information and text, and measure it.
// set it up -- put the variable somewhere globally or contextually accessible, as necessary
var textRuler = paper.text( -10000, -10000, '' ).attr( { fill: 'none', stroke: 'none' } );
function getTextWidth( text, fontFamily, fontSize )
{
textResult.attr( { text: text, 'font-family': fontFamily, 'font-size': fontSize } );
var bbox = textResult.getBBox();
return bbox.width;
}
It's not elegant by any stretch of the imagination. But it will do you want with relatively little overhead and no complexity.
Cufonized Font
If you were willing to consider using a cufonized font, you could calculate the size of a given text string without needing to mess with the DOM at all. In fact, this is probably approximately what the canvas's elements measureText
method does behind the scenes. Given an imported font, you would simply do something like this (consider this protocode!)
// font should be the result of a call to paper.[getFont][2] for a cufonized font
function getCufonWidth( text, font, fontSize )
{
var textLength = text.length, cufonWidth = 0;
for ( var i = 0; i < textLength; i++ )
{
var thisChar = text[i];
if ( ! font.glyphs[thisChar] || ! font.glyphs[thisChar].w )
continue; // skip missing glyphs and/or 0-width entities
cufonWidth += font.glyphs[thisChar].w / font.face['units-per-em'] * fontSize;
}
return cufonWidth;
}
I really like working with cufonized fonts -- in terms of their capacity for being animated in interesting ways, they are far more useful than text. But this second approach may be more additional complexity than you need or want.