ОБНОВИТЬ - для примера этой работы я использовал эту технику в редакторе Carota .
Следуя ответу ellisbben, вот улучшенная версия для получения подъема и спуска от базовой линии, то есть такая же, как tmAscent
и tmDescent
возвращенная Win32 GetTextMetric API. Это необходимо, если вы хотите выполнить обтекание текстом с разным шрифтом / размером.
Приведенное выше изображение было сгенерировано на холсте в Safari, красная линия - это верхняя строка, где холсту было приказано нарисовать текст, зеленый - базовая линия, а синий - нижняя (таким образом, красный или синий - полная высота).
Использование jQuery для краткости:
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;
};
В дополнение к текстовому элементу я добавляю div с помощью, display: inline-block
чтобы я мог установить его vertical-align
стиль, а затем выяснить, куда его поместил браузер.
Таким образом, вы получаете объект с ascent
, descent
и height
(что просто ascent
+ descent
для удобства). Чтобы проверить это, стоит иметь функцию, которая рисует горизонтальную линию:
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();
};
Затем вы можете увидеть, как текст располагается на холсте относительно верха, базовой линии и низа:
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');