Testing fillText vs HTML rendering
letter-spacing seems to be different on Firefox 6. (Haven't tested on previous versions of Firefox). If you disable direct2d on Firefox (via about:config). The widths reported are same.
by davidhong
HTML
<div><p>Hello, World! Avalon is my hero</p></div>
<canvas id="c" width="300" height="25"></canvas>
<canvas id="d" width="300" height="25"></canvas>
CSS
div, canvas { margin: 0; padding: 0; width: 300px; height: 25px; border: 1px dotted #222; position: absolute; left: 0; }
div { top: 0; }
p { bottom: 0; left: 0; position: absolute; font: normal normal 400 12px/12px Monaco; margin: 0; padding: 0; }
#c { top: 30px; }
#d { top: 60px; }
JavaScript
var log = function() {
if (typeof console !== 'undefined' && console.log) {
console.log(Array.prototype.slice.call(arguments));
}
};
/**
* fillTextCharByChar
*
* uses measureText() to progress forward on x-axis; Uses fillText() on
* each individual char instead of the whole string.
*
* @param context {CanvasRenderingContext2D}
* @param text {string}
* @param x {number}
* @param y {number}
*/
var fillTextCharByChar = function(context, text, x, y) {
text = String(text);
var charlist = String.prototype.split.call(text, ''),
charlen = charlist.length,
current = 0,
position = x;
for (; current < charlen; current += 1) {
var char = charlist[current],
charwidth = context.measureText(char).width;
context.fillText(char, position, y);
position += charwidth;
}
log('fillTextCharByChar', text, position);
};
(function(document) {
var c = document.getElementById('c'),
d = document.getElementById('d'),
cctx = c.getContext('2d'),
dctx = d.getContext('2d'),
text = 'Hello, World! Avalon is my hero';
// Set both canvas elements to have same font styling
cctx.font = dctx.font = 'normal normal 400 12px/12px Monaco';
// First method uses the built-in fillText method
cctx.fillText(text, 0, 22);
log('fillText', text, cctx.measureText(text).width);
// Second method is to use individual character and their measureText().width to progress on x-coordinate vector
fillTextCharByChar(dctx, text, 0, 22);
}(document));