tamaño - buscar texto en pagina web javascript
¿Cómo puede encontrar la altura del texto en un lienzo HTML? (20)
La especificación tiene una función context.measureText (texto) que le indicará cuánto ancho requeriría para imprimir ese texto, pero no puedo encontrar una manera de averiguar qué tan alto es. Sé que está basado en la fuente, pero no sé convertir una cadena de fuente a una altura de texto.
¿No es la altura del texto en píxeles igual al tamaño de la fuente (en pts) si define la fuente con context.font?
Aquí hay una función simple. No se necesita biblioteca
Escribí esta función para obtener los límites superior e inferior relativos a la línea de base. Si textBaseline
está establecido en alphabetic
. Lo que hace es crear otro lienzo, y luego dibuja allí, y luego encuentra el pixel no en blanco más alto y más abajo. Y ese es el límite superior e inferior. Lo devuelve como relativo, por lo que si la altura es 20px, y no hay nada debajo de la línea base, entonces el límite superior es -20
.
Debe proporcionarle caracteres. De lo contrario, le dará 0 alto y 0 ancho, obviamente.
Uso:
alert(measureHeight(''40px serif'', 40, ''rg'').height)
Aquí está la función:
function measureHeight(aFont, aSize, aChars, aOptions={}) {
// if you do pass aOptions.ctx, keep in mind that the ctx properties will be changed and not set back. so you should have a devoted canvas for this
// if you dont pass in a width to aOptions, it will return it to you in the return object
// the returned width is Math.ceil''ed
console.error(''aChars: "'' + aChars + ''"'');
var defaultOptions = {
width: undefined, // if you specify a width then i wont have to use measureText to get the width
canAndCtx: undefined, // set it to object {can:,ctx:} // if not provided, i will make one
range: 3
};
aOptions.range = aOptions.range || 3; // multiples the aSize by this much
if (aChars === '''') {
// no characters, so obviously everything is 0
return {
relativeBot: 0,
relativeTop: 0,
height: 0,
width: 0
};
// otherwise i will get IndexSizeError: Index or size is negative or greater than the allowed amount error somewhere below
}
// validateOptionsObj(aOptions, defaultOptions); // not needed because all defaults are undefined
var can;
var ctx;
if (!aOptions.canAndCtx) {
can = document.createElement(''canvas'');;
can.mozOpaque = ''true''; // improved performanceo on firefox i guess
ctx = can.getContext(''2d'');
// can.style.position = ''absolute'';
// can.style.zIndex = 10000;
// can.style.left = 0;
// can.style.top = 0;
// document.body.appendChild(can);
} else {
can = aOptions.canAndCtx.can;
ctx = aOptions.canAndCtx.ctx;
}
var w = aOptions.width;
if (!w) {
ctx.textBaseline = ''alphabetic'';
ctx.textAlign = ''left'';
ctx.font = aFont;
w = ctx.measureText(aChars).width;
}
w = Math.ceil(w); // needed as i use w in the calc for the loop, it needs to be a whole number
// must set width/height, as it wont paint outside of the bounds
can.width = w;
can.height = aSize * aOptions.range;
ctx.font = aFont; // need to set the .font again, because after changing width/height it makes it forget for some reason
ctx.textBaseline = ''alphabetic'';
ctx.textAlign = ''left'';
ctx.fillStyle = ''white'';
console.log(''w:'', w);
var avgOfRange = (aOptions.range + 1) / 2;
var yBaseline = Math.ceil(aSize * avgOfRange);
console.log(''yBaseline:'', yBaseline);
ctx.fillText(aChars, 0, yBaseline);
var yEnd = aSize * aOptions.range;
var data = ctx.getImageData(0, 0, w, yEnd).data;
// console.log(''data:'', data)
var botBound = -1;
var topBound = -1;
// measureHeightY:
for (y=0; y<=yEnd; y++) {
for (var x = 0; x < w; x += 1) {
var n = 4 * (w * y + x);
var r = data[n];
var g = data[n + 1];
var b = data[n + 2];
// var a = data[n + 3];
if (r+g+b > 0) { // non black px found
if (topBound == -1) {
topBound = y;
}
botBound = y; // break measureHeightY; // dont break measureHeightY ever, keep going, we till yEnd. so we get proper height for strings like "`." or ":" or "!"
break;
}
}
}
return {
relativeBot: botBound - yBaseline, // relative to baseline of 0 // bottom most row having non-black
relativeTop: topBound - yBaseline, // relative to baseline of 0 // top most row having non-black
height: (botBound - topBound) + 1,
width: w// EDIT: comma has been added to fix old broken code.
};
}
relativeBot
, relativeTop
y height
son las cosas útiles en el objeto de devolución.
Aquí hay un ejemplo de uso:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>
function measureHeight(aFont, aSize, aChars, aOptions={}) {
// if you do pass aOptions.ctx, keep in mind that the ctx properties will be changed and not set back. so you should have a devoted canvas for this
// if you dont pass in a width to aOptions, it will return it to you in the return object
// the returned width is Math.ceil''ed
console.error(''aChars: "'' + aChars + ''"'');
var defaultOptions = {
width: undefined, // if you specify a width then i wont have to use measureText to get the width
canAndCtx: undefined, // set it to object {can:,ctx:} // if not provided, i will make one
range: 3
};
aOptions.range = aOptions.range || 3; // multiples the aSize by this much
if (aChars === '''') {
// no characters, so obviously everything is 0
return {
relativeBot: 0,
relativeTop: 0,
height: 0,
width: 0
};
// otherwise i will get IndexSizeError: Index or size is negative or greater than the allowed amount error somewhere below
}
// validateOptionsObj(aOptions, defaultOptions); // not needed because all defaults are undefined
var can;
var ctx;
if (!aOptions.canAndCtx) {
can = document.createElement(''canvas'');;
can.mozOpaque = ''true''; // improved performanceo on firefox i guess
ctx = can.getContext(''2d'');
// can.style.position = ''absolute'';
// can.style.zIndex = 10000;
// can.style.left = 0;
// can.style.top = 0;
// document.body.appendChild(can);
} else {
can = aOptions.canAndCtx.can;
ctx = aOptions.canAndCtx.ctx;
}
var w = aOptions.width;
if (!w) {
ctx.textBaseline = ''alphabetic'';
ctx.textAlign = ''left'';
ctx.font = aFont;
w = ctx.measureText(aChars).width;
}
w = Math.ceil(w); // needed as i use w in the calc for the loop, it needs to be a whole number
// must set width/height, as it wont paint outside of the bounds
can.width = w;
can.height = aSize * aOptions.range;
ctx.font = aFont; // need to set the .font again, because after changing width/height it makes it forget for some reason
ctx.textBaseline = ''alphabetic'';
ctx.textAlign = ''left'';
ctx.fillStyle = ''white'';
console.log(''w:'', w);
var avgOfRange = (aOptions.range + 1) / 2;
var yBaseline = Math.ceil(aSize * avgOfRange);
console.log(''yBaseline:'', yBaseline);
ctx.fillText(aChars, 0, yBaseline);
var yEnd = aSize * aOptions.range;
var data = ctx.getImageData(0, 0, w, yEnd).data;
// console.log(''data:'', data)
var botBound = -1;
var topBound = -1;
// measureHeightY:
for (y=0; y<=yEnd; y++) {
for (var x = 0; x < w; x += 1) {
var n = 4 * (w * y + x);
var r = data[n];
var g = data[n + 1];
var b = data[n + 2];
// var a = data[n + 3];
if (r+g+b > 0) { // non black px found
if (topBound == -1) {
topBound = y;
}
botBound = y; // break measureHeightY; // dont break measureHeightY ever, keep going, we till yEnd. so we get proper height for strings like "`." or ":" or "!"
break;
}
}
}
return {
relativeBot: botBound - yBaseline, // relative to baseline of 0 // bottom most row having non-black
relativeTop: topBound - yBaseline, // relative to baseline of 0 // top most row having non-black
height: (botBound - topBound) + 1,
width: w
};
}
</script>
</head>
<body style="background-color:steelblue;">
<input type="button" value="reuse can" onClick="alert(measureHeight(''40px serif'', 40, ''rg'', {canAndCtx:{can:document.getElementById(''can''), ctx:document.getElementById(''can'').getContext(''2d'')}}).height)">
<input type="button" value="dont reuse can" onClick="alert(measureHeight(''40px serif'', 40, ''rg'').height)">
<canvas id="can"></canvas>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
</html>
El relativeBot
y relativeTop
son lo que ves en esta imagen aquí:
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text
Como sugiere JJ Stiff, puede agregar su texto a un lapso y luego medir el offset Height del lapso.
var d = document.createElement("span");
d.font = "20px arial";
d.textContent = "Hello world!";
document.body.appendChild(d);
var emHeight = d.offsetHeight;
document.body.removeChild(d);
Como se muestra en HTML5Rocks
EDITAR: ¿Estás utilizando transformaciones de lienzo? Si es así, deberá seguir la matriz de transformación. El siguiente método debería medir la altura del texto con la transformación inicial.
EDIT # 2: Curiosamente, el código siguiente no produce respuestas correctas cuando lo ejecuto en esta página de ; Es muy posible que la presencia de algunas reglas de estilo pueda romper esta función.
El lienzo utiliza fuentes definidas por CSS, por lo que, en teoría, podemos agregar un trozo de texto con el estilo adecuado al documento y medir su altura. Creo que esto es significativamente más fácil que renderizar texto y luego verificar los datos de píxeles y también debe respetar los ascendentes y descendentes. Mira lo siguiente:
var determineFontHeight = function(fontStyle) {
var body = document.getElementsByTagName("body")[0];
var dummy = document.createElement("div");
var dummyText = document.createTextNode("M");
dummy.appendChild(dummyText);
dummy.setAttribute("style", fontStyle);
body.appendChild(dummy);
var result = dummy.offsetHeight;
body.removeChild(dummy);
return result;
};
//A little test...
var exampleFamilies = ["Helvetica", "Verdana", "Times New Roman", "Courier New"];
var exampleSizes = [8, 10, 12, 16, 24, 36, 48, 96];
for(var i = 0; i < exampleFamilies.length; i++) {
var family = exampleFamilies[i];
for(var j = 0; j < exampleSizes.length; j++) {
var size = exampleSizes[j] + "pt";
var style = "font-family: " + family + "; font-size: " + size + ";";
var pixelHeight = determineFontHeight(style);
console.log(family + " " + size + " ==> " + pixelHeight + " pixels high.");
}
}
Tendrá que asegurarse de obtener el estilo de fuente correcto en el elemento DOM que mide la altura, pero eso es bastante sencillo; realmente deberías usar algo como
var canvas = /* ... */
var context = canvas.getContext("2d");
var canvasFont = " ... ";
var fontHeight = determineFontHeight("font: " + canvasFont + ";");
context.font = canvasFont;
/*
do your stuff with your font and its height here.
*/
En primer lugar, debe establecer la altura de un tamaño de fuente, y luego de acuerdo con el valor de la altura de la fuente para determinar la altura actual de su texto es cuánto, líneas de texto cruzado, por supuesto, la misma altura de la fuente la fuente necesita acumularse, si el texto no excede el cuadro de texto más grande. Alto, todo mostrar; de lo contrario, solo muestre el texto dentro del texto del cuadro. Los valores altos necesitan su propia definición. Cuanto mayor sea la altura preestablecida, mayor será la altura del texto que se debe mostrar e interceptar.
Después de que el efecto se procesa (resolver)
Antes de que se procese el efecto (sin resolver)
AutoWrappedText.auto_wrap = function(ctx, text, maxWidth, maxHeight) {
var words = text.split("");
var lines = [];
var currentLine = words[0];
var total_height = 0;
for (var i = 1; i < words.length; i++) {
var word = words[i];
var width = ctx.measureText(currentLine + word).width;
if (width < maxWidth) {
currentLine += word;
} else {
lines.push(currentLine);
currentLine = word;
// TODO dynamically get font size
total_height += 25;
if (total_height >= maxHeight) {
break
}
}
}
if (total_height + 25 < maxHeight) {
lines.push(currentLine);
} else {
lines[lines.length - 1] += "…";
}
return lines;};
Encontré que JUST FOR ARIAL la forma más simple, rápida y precisa de encontrar la altura del cuadro delimitador es usar el ancho de ciertas letras. Si planea usar una fuente determinada sin dejar que el usuario elija una diferente, puede hacer una pequeña investigación para encontrar la letra correcta que hace el trabajo para esa fuente.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="700" height="200" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "100px Arial";
var txt = "Hello guys!"
var Hsup=ctx.measureText("H").width;
var Hbox=ctx.measureText("W").width;
var W=ctx.measureText(txt).width;
var W2=ctx.measureText(txt.substr(0, 9)).width;
ctx.fillText(txt, 10, 100);
ctx.rect(10,100, W, -Hsup);
ctx.rect(10,100+Hbox-Hsup, W2, -Hbox);
ctx.stroke();
</script>
<p><strong>Note:</strong> The canvas tag is not supported in Internet
Explorer 8 and earlier versions.</p>
</body>
</html>
Es curioso que TextMetrics solo tenga ancho y no alto:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#textmetrics
¿Puedes usar un Span como en este ejemplo?
http://mudcu.be/journal/2011/01/html5-typographic-metrics/#alignFix
Esto está enloqueciendo ... La altura del texto es el tamaño de la fuente ... ¿Alguno de ustedes no leyó la documentación?
context.font = "22px arial";
esto establecerá la altura a 22px.
la única razón por la que hay un ..
context.measureText(string).width
is because that the width of the string can not be determined unless it knows the string you want the width of but for all the strings drawn with the font.. the height will be 22px.
if you use another measurement than px then the height will still be the same but with that measurement so at most all you would have to do is convert the measurement.
Estoy escribiendo un emulador de terminal, así que necesitaba dibujar rectángulos alrededor de los caracteres.
var size = 10
var lineHeight = 1.2 // CSS "line-height: normal" is between 1 and 1.2
context.font = size+''px/''+lineHeight+''em monospace''
width = context.measureText(''m'').width
height = size * lineHeight
Obviamente, si quieres la cantidad exacta de espacio que ocupa el personaje, no será de ayuda. Pero te dará una buena aproximación para ciertos usos.
Implementé una buena biblioteca para medir la altura y el ancho exactos del texto utilizando el lienzo HTML. Esto debería hacer lo que quieras.
La especificación del lienzo no nos da un método para medir la altura de una cuerda. Sin embargo, puede establecer el tamaño del texto en píxeles y, por lo general, puede averiguar qué límites verticales son relativamente fáciles.
Si necesita algo más preciso, puede lanzar texto en el lienzo y luego obtener datos de píxeles y averiguar cuántos píxeles se utilizan verticalmente. Esto sería relativamente simple, pero no muy eficiente. Podrías hacer algo como esto (funciona, pero dibuja algún texto en tu lienzo que quieras eliminar):
function measureTextHeight(ctx, left, top, width, height) {
// Draw the text in the specified area
ctx.save();
ctx.translate(left, top + Math.round(height * 0.8));
ctx.mozDrawText(''gM''); // This seems like tall text... Doesn''t it?
ctx.restore();
// Get the pixel data from the canvas
var data = ctx.getImageData(left, top, width, height).data,
first = false,
last = false,
r = height,
c = 0;
// Find the last line with a non-white pixel
while(!last && r) {
r--;
for(c = 0; c < width; c++) {
if(data[r * width * 4 + c * 4 + 3]) {
last = r;
break;
}
}
}
// Find the first line with a non-white pixel
while(r) {
r--;
for(c = 0; c < width; c++) {
if(data[r * width * 4 + c * 4 + 3]) {
first = r;
break;
}
}
// If we''ve got it then return the height
if(first != r) return last - first;
}
// We screwed something up... What do you expect from free code?
return 0;
}
// Set the font
context.mozTextStyle = ''32px Arial'';
// Specify a context and a rect that is safe to draw in when calling measureTextHeight
var height = measureTextHeight(context, 0, 0, 50, 50);
console.log(height);
Para Bespin falsifican una altura midiendo el ancho de una ''m'' minúscula ... No sé cómo se usa esto, y no recomendaría este método. Aquí está el método relevante de Bespin:
var fixCanvas = function(ctx) {
// upgrade Firefox 3.0.x text rendering to HTML 5 standard
if (!ctx.fillText && ctx.mozDrawText) {
ctx.fillText = function(textToDraw, x, y, maxWidth) {
ctx.translate(x, y);
ctx.mozTextStyle = ctx.font;
ctx.mozDrawText(textToDraw);
ctx.translate(-x, -y);
}
}
if (!ctx.measureText && ctx.mozMeasureText) {
ctx.measureText = function(text) {
ctx.mozTextStyle = ctx.font;
var width = ctx.mozMeasureText(text);
return { width: width };
}
}
if (ctx.measureText && !ctx.html5MeasureText) {
ctx.html5MeasureText = ctx.measureText;
ctx.measureText = function(text) {
var textMetrics = ctx.html5MeasureText(text);
// fake it ''til you make it
textMetrics.ascent = ctx.html5MeasureText("m").width;
return textMetrics;
}
}
// for other browsers
if (!ctx.fillText) {
ctx.fillText = function() {}
}
if (!ctx.measureText) {
ctx.measureText = function() { return 10; }
}
};
Los navegadores están comenzando a admitir las métricas de texto avanzadas , lo que hará que esta tarea resulte trivial cuando sea ampliamente compatible:
let metrics = ctx.measureText(text);
let fontHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
let actualHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
fontHeight
le proporciona la altura del cuadro delimitador que es constante independientemente de la cadena que se esté procesando. actualHeight
es específico de la cadena que se está procesando.
Spec: https://www.w3.org/TR/2012/CR-2dcontext-20121217/#dom-textmetrics-fontboundingboxascent y las secciones justo debajo de él.
Estado de soporte (20-Ago-2017):
- Chrome lo tiene detrás de una bandera ( https://bugs.chromium.org/p/chromium/issues/detail?id=277215 ).
- Firefox lo tiene en desarrollo ( https://bugzilla.mozilla.org/show_bug.cgi?id=1102584 ).
- Edge no tiene soporte ( https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/30922861-advanced-canvas-textmetrics ).
- node-canvas (módulo node.js), principalmente compatible ( https://github.com/Automattic/node-canvas/wiki/Compatibility-Status ).
No estoy seguro, pero recuerdo que Dion Almaer dijo algo sobre esto en una presentación de Google IO sobre Mozilla Bespin . Fue algo acerca de darle la vuelta a la letra M y luego medir su ancho. Pero puedo estar equivocado.
Puede obtener una aproximación muy cercana de la altura vertical al verificar la longitud de una M. mayúscula.
ctx.font=''bold 10px Arial'';
lineHeight=ctx.measureText(''M'').width;
Resolví este problema de forma directa, utilizando la manipulación de píxeles.
Aquí hay una respuesta gráfica:
Aquí está el código:
function textHeight (text, font) {
var fontDraw = document.createElement("canvas");
var height = 100;
var width = 100;
// here we expect that font size will be less canvas geometry
fontDraw.setAttribute("height", height);
fontDraw.setAttribute("width", width);
var ctx = fontDraw.getContext(''2d'');
// black is default
ctx.fillRect(0, 0, width, height);
ctx.textBaseline = ''top'';
ctx.fillStyle = ''white'';
ctx.font = font;
ctx.fillText(text/*''Eg''*/, 0, 0);
var pixels = ctx.getImageData(0, 0, width, height).data;
// row numbers where we first find letter end where it ends
var start = -1;
var end = -1;
for (var row = 0; row < height; row++) {
for (var column = 0; column < width; column++) {
var index = (row * width + column) * 4;
// if pixel is not white (background color)
if (pixels[index] == 0) {
// we havent met white (font color) pixel
// on the row and the letters was detected
if (column == width - 1 && start != -1) {
end = row;
row = height;
break;
}
continue;
}
else {
// we find top of letter
if (start == -1) {
start = row;
}
// ..letters body
break;
}
}
}
/*
document.body.appendChild(fontDraw);
fontDraw.style.pixelLeft = 400;
fontDraw.style.pixelTop = 400;
fontDraw.style.position = "absolute";
*/
return end - start;
}
Sin embargo, configurar el tamaño de la fuente podría no ser práctico, desde la configuración
ctx.font = ''''
utilizará el definido por CSS, así como cualquier etiqueta de fuente incrustada. Si usa la fuente CSS, no tiene idea de cuál es la altura de forma programática, utilizando el método measureText, que es muy miope. Sin embargo, en otra nota, IE8 devuelve el ancho y la altura.
Solo para agregar a la respuesta de Daniel (¡que es genial! ¡Y absolutamente correcta!), Versión sin JQuery:
function objOff(obj)
{
var currleft = currtop = 0;
if( obj.offsetParent )
{ do { currleft += obj.offsetLeft; currtop += obj.offsetTop; }
while( obj = obj.offsetParent ); }
else { currleft += obj.offsetLeft; currtop += obj.offsetTop; }
return [currleft,currtop];
}
function FontMetric(fontName,fontSize)
{
var text = document.createElement("span");
text.style.fontFamily = fontName;
text.style.fontSize = fontSize + "px";
text.innerHTML = "ABCjgq|";
// if you will use some weird fonts, like handwriting or symbols, then you need to edit this test string for chars that will have most extreme accend/descend values
var block = document.createElement("div");
block.style.display = "inline-block";
block.style.width = "1px";
block.style.height = "0px";
var div = document.createElement("div");
div.appendChild(text);
div.appendChild(block);
// this test div must be visible otherwise offsetLeft/offsetTop will return 0
// but still let''s try to avoid any potential glitches in various browsers
// by making it''s height 0px, and overflow hidden
div.style.height = "0px";
div.style.overflow = "hidden";
// I tried without adding it to body - won''t work. So we gotta do this one.
document.body.appendChild(div);
block.style.verticalAlign = "baseline";
var bp = objOff(block);
var tp = objOff(text);
var taccent = bp[1] - tp[1];
block.style.verticalAlign = "bottom";
bp = objOff(block);
tp = objOff(text);
var theight = bp[1] - tp[1];
var tdescent = theight - taccent;
// now take it off :-)
document.body.removeChild(div);
// return text accent, descent and total height
return [taccent,theight,tdescent];
}
Acabo de probar el código anterior y funciona muy bien con las últimas Chrome, FF y Safari en Mac.
EDITAR: He agregado el tamaño de fuente y probado con webfont en lugar de la fuente del sistema. Funciona de maravilla.
respuesta de una línea
var height = parseInt(ctx.font) * 1.2;
CSS "línea-altura: normal" está entre 1 y 1.2
lea here para más información
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 base, es decir, lo mismo que tmAscent
y tmDescent
devueltos por la API GetTextMetric de Win32. Esto es necesario si desea realizar una secuencia de texto envuelta en palabras con tramos en diferentes fuentes / tamaños.
La imagen de arriba se generó en un lienzo en Safari, el rojo fue la línea superior donde se le dijo al lienzo que dibujara el texto, el verde era la línea de fondo y el azul era el fondo (así que de rojo a azul es la altura completa).
Usando jQuery para sucinctness:
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 display: inline-block
para que pueda establecer su estilo de vertical-align
y luego averiguar dónde lo ha ubicado 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 dibuja 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 posiciona el texto en el lienzo en relación con la parte superior, la línea de 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'');
In normal situations the following should work:
var can = CanvasElement.getContext(''2d''); //get context
var lineHeight = /[0-9]+(?=pt|px)/.exec(can.font); //get height from font variable