ACTUALIZACIÓN : para un ejemplo de este trabajo, utilicé esta técnica en el editor de Carota .
A continuación de la respuesta de ellisbben, aquí hay una versión mejorada para obtener el ascenso y el descenso desde la línea de base, es decir, la misma tmAscent
y tmDescent
devuelta por la API GetTextMetric de Win32 . Esto es necesario si desea hacer una ejecución de texto en formato de palabra con tramos en diferentes fuentes / tamaños.
La imagen de arriba se generó en un lienzo en Safari, siendo el rojo la línea superior donde se le dijo al lienzo que dibujara el texto, el verde como la línea de base y el azul como la parte inferior (de rojo a azul es la altura completa).
Usando jQuery para ser sucinto:
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;
};
Además de un elemento de texto, agrego un div con el display: inline-block
que puedo configurar su vertical-align
estilo y luego averiguar dónde lo ha colocado el navegador.
Entonces recuperas un objeto con ascent
, descent
y height
(que es solo ascent
+ descent
por conveniencia). Para probarlo, vale la pena tener una función que dibuje una línea horizontal:
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();
};
Luego puede ver cómo se coloca el texto en el lienzo en relación con la parte superior, la línea base y la parte inferior:
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');