UPDATE - pour un exemple de ce fonctionnement, j'ai utilisé cette technique dans la Éditeur de carottes .
Suite à la réponse d'ellisbben, voici une version améliorée qui permet d'obtenir l'ascension et la descente à partir de la ligne de base, c'est-à-dire comme suit tmAscent
et tmDescent
renvoyée par la fonction Win32 GetTextMetric API. Ceci est nécessaire si vous voulez faire un tirage de texte avec des espaces dans des polices/tailles différentes.
L'image ci-dessus a été générée sur un canevas dans Safari, le rouge étant la ligne supérieure où l'on a demandé au canevas de dessiner le texte, le vert étant la ligne de base et le bleu étant le bas (ainsi, de rouge à bleu, la hauteur totale).
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
afin que je puisse définir son vertical-align
et ensuite trouver où le navigateur l'a placé.
Vous récupérez donc un objet avec ascent
, descent
et height
(qui est juste ascent
+ descent
pour plus de commodité). Pour le tester, il est intéressant d'avoir une fonction qui dessine 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();
};
Vous pouvez alors 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');
1 votes
J'aimerais connaître un meilleur moyen que la réponse ci-dessus. S'il existe un algorithme permettant de prendre une police de points arbitraires et de trouver les limites max/min sur celle-ci, je serais très heureux de l'entendre. =)
0 votes
@tjameson - il semble que oui. Voir la réponse d'ellisbben (et le complément que j'y ai apporté).
2 votes
Je me demande si le caractère Unicode "FULL BLOCK" (U+2588) peut être utilisé comme une approximation en multipliant sa largeur par deux.
1 votes
Il convient de noter que la réponse dépend un peu de vos exigences. Par exemple, la hauteur requise pour rendre le caractère "a" est différente de celle requise pour rendre le caractère "y", en raison de la descendance qui s'étend sous la ligne de base de la police. Les réponses HTML ci-dessous ne tiennent pas compte de ce facteur et vous donneront une hauteur générale appropriée pour n'importe quel texte, tandis que la réponse de @Noitidart donne une hauteur plus exacte pour un texte spécifique.
5 votes
Rappelez-vous que vous pouvez avoir des caractères qui ressemblent à ceci
M
Il s'agit donc d'un problème très délicat à résoudre dans le cas général.0 votes
Lorsque vous travaillez avec un élément de texte SVG
t
vous pouvez obtenir la hauteur part.getBBox().height
après avoir appliqué les styles pertinents viat.setAttribute(...)
. Donc si la hauteur correspond à celle de la toile, cela peut être une façon plus simple de calculer la hauteur.