CẬP NHẬT - cho một ví dụ về hoạt động này, tôi đã sử dụng kỹ thuật này trong trình chỉnh sửa Carota .
Tiếp theo từ câu trả lời của ellvdben, đây là một phiên bản nâng cao để có được sự đi lên và đi xuống từ đường cơ sở, tức là giống như tmAscent
và được tmDescent
trả về bởi API GetTextMetric của Win32 . Điều này là cần thiết nếu bạn muốn thực hiện một dòng văn bản được bao bọc bằng các nhịp với các phông chữ / kích cỡ khác nhau.
Hình ảnh trên được tạo trên một khung vẽ trong Safari, màu đỏ là dòng trên cùng trong đó khung vẽ được yêu cầu vẽ văn bản, màu xanh lá cây là đường cơ sở và màu xanh lam là đáy (vì vậy màu đỏ thành màu xanh là chiều cao đầy đủ).
Sử dụng jQuery cho gọn gàng:
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;
};
Ngoài một yếu tố văn bản, tôi thêm một div với display: inline-block
để tôi có thể đặt vertical-align
kiểu của nó và sau đó tìm xem trình duyệt đã đặt nó ở đâu.
Vì vậy, bạn nhận lại một đối tượng với ascent
, descent
và height
(chỉ là ascent
+ descent
để thuận tiện). Để kiểm tra nó, đáng để có một hàm vẽ một đường ngang:
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();
};
Sau đó, bạn có thể thấy cách văn bản được định vị trên khung vẽ so với đầu, đường cơ sở và dưới cùng:
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');