MISE À JOUR - pour un exemple de ce fonctionnement, j'ai utilisé cette technique dans l' éditeur Carota .
Dans le prolongement de la réponse d'ellisbben, voici une version améliorée pour obtenir l'ascension et la descente à partir de la ligne de base, c'est-à-dire identiques tmAscent
et tmDescent
renvoyées par l' API GetTextMetric de Win32 . Ceci est nécessaire si vous souhaitez créer une séquence de texte enveloppée de mots avec des étendues dans différentes polices / tailles.
L'image ci-dessus a été générée sur un canevas dans Safari, le rouge étant la ligne supérieure où le canevas a été invité à dessiner le texte, le vert étant la ligne de base et le bleu étant le bas (donc le rouge au bleu est la pleine hauteur).
Utilisation de jQuery pour la concision:
var getTextHeight = function(font) {
var text = $('<span>Hg</span>').css({ fontFamily: font });
var block = $('<div style="display: inline-block; width: 1px; height: 0px;"></div>');
var div = $('<div></div>');
div.append(text, block);
var body = $('body');
body.append(div);
try {
var result = {};
block.css({ verticalAlign: 'baseline' });
result.ascent = block.offset().top - text.offset().top;
block.css({ verticalAlign: 'bottom' });
result.height = block.offset().top - text.offset().top;
result.descent = result.height - result.ascent;
} finally {
div.remove();
}
return result;
};
En plus d'un élément de texte, j'ajoute un div avec display: inline-block
pour pouvoir définir sonvertical-align
style, puis savoir où le navigateur l'a mis.
Vous récupérez donc un objet avec ascent
, descent
et height
(ce qui est juste ascent
+ descent
pour plus de commodité). Pour le tester, cela vaut la peine d'avoir une fonction qui trace une ligne horizontale:
var testLine = function(ctx, x, y, len, style) {
ctx.strokeStyle = style;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + len, y);
ctx.closePath();
ctx.stroke();
};
Ensuite, vous pouvez voir comment le texte est positionné sur le canevas par rapport au haut, à la ligne de base et au bas:
var font = '36pt Times';
var message = 'Big Text';
ctx.fillStyle = 'black';
ctx.textAlign = 'left';
ctx.textBaseline = 'top'; // important!
ctx.font = font;
ctx.fillText(message, x, y);
// Canvas can tell us the width
var w = ctx.measureText(message).width;
// New function gets the other info we need
var h = getTextHeight(font);
testLine(ctx, x, y, w, 'red');
testLine(ctx, x, y + h.ascent, w, 'green');
testLine(ctx, x, y + h.height, w, 'blue');