AGGIORNAMENTO - per un esempio di questo lavoro, ho usato questa tecnica nell'editor Carota .
Seguendo la risposta di ellisbben, ecco una versione migliorata per ottenere l'ascesa e la discesa dalla linea di base, ovvero la stessa tmAscent
e tmDescent
restituita dall'API GetTextMetric di Win32 . Ciò è necessario se si desidera eseguire una sequenza di testo a capo di testo con span in caratteri / dimensioni diversi.
L'immagine sopra è stata generata su una tela in Safari, il rosso è la linea superiore in cui è stato detto alla tela di disegnare il testo, il verde è la linea di base e il blu è la parte inferiore (quindi il rosso al blu è l'altezza massima).
Utilizzo di jQuery per la sintonia:
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;
};
Oltre a un elemento di testo, aggiungo un div con display: inline-block
modo da poter impostare il suo vertical-align
stile e quindi scoprire dove lo ha inserito il browser.
Quindi ottieni un oggetto con ascent
, descent
e height
(che è solo ascent
+descent
per comodità). Per provarlo, vale la pena avere una funzione che disegna una linea orizzontale:
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();
};
Quindi puoi vedere come viene posizionato il testo nell'area di disegno rispetto alla parte superiore, alla linea di base e alla parte inferiore:
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');