Skip to content

Instantly share code, notes, and snippets.

@poeschko
Created January 4, 2012 21:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poeschko/1562233 to your computer and use it in GitHub Desktop.
Save poeschko/1562233 to your computer and use it in GitHub Desktop.
JavaScript text width
function cached(func) {
cache = {};
return function() {
var args = [];
for (var i = 0; i < arguments.length; ++i)
args.push(arguments[i]);
var key = $.param({args: args});
var value = cache[key];
if (typeof value != "undefined")
return value;
value = func.apply(this, arguments);
cache[key] = value;
return value;
}
}
function TextMetrics(style) {
var element = document.createElement("span");
this.element = $(element);
this.element.css({
visibility: "hidden",
position: "absolute",
left: "-10000px"
});
document.body.appendChild(element);
if (style)
this.element.css(style); // apply additional styles
this.getWidth = cached(function(text) {
if (text.length > 2) {
var total = 0;
for (var i = 0; i < text.length; ++i) {
total += this.getWidth(text[i]);
if (i > 0)
total += this.getSpacing(text[i - 1], text[i]);
}
return total;
} else {
return this.getWidthDOM(text);
}
});
this.getSpacing = function(char1, char2) {
return this.getWidth(char1 + char2) - this.getWidth(char1) - this.getWidth(char2);
}
this.getWidthDOM = function(text) {
var node = document.createTextNode(text);
if (element.firstChild)
element.replaceChild(node, element.firstChild);
else
element.appendChild(node);
return this.element.width();
}
}
var metrics = new TextMetrics({"font-family": "Helvetica Neue", "font-size": "20pt"});
var text = "ffaaaaaaaaff";
console.log("text: '" + text + "'; correct: " + metrics.getWidthDOM(text) + "; estimated: " + metrics.getWidth(text));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment