Вычислить точный символ \ высоту строки в JavaScript
Я работаю с холстами и не могу придумать какое-либо решение или найти ответ на мою проблему.
У меня есть шрифт, который содержит символы \ символы разных размеров - высоты и ширины.
Я хочу нарисовать некоторые символы (символы) из шрифта, а некоторые сверху \ вниз символа. Проблема в том, что я не могу найти способ получить точную высоту в пикселях символа, который я рисую, и это вызывает нежелательные пробелы между центральным символом и символом сверху \ вниз (для получения ширины В строке есть функция context.measureText(theText)).
например допустим, я хочу, чтобы символом "Х" был мой центральный символ. и '-' чтобы быть на вершине. Это выглядит так
-
Икс
но теперь между 'X' и '-' есть место, которое я не хочу.
Кто-нибудь может мне с этим помочь?
Спасибо
3 ответа
Ширина проста: контекст холста имеет встроенную метрику для измерения ширины текста.
// this will measure text width
context.font = '14pt Verdana';
var m=context.measureText(yourText);
var theWidth=m.width;
Высота сложнее, потому что measureText не вычисляет высоту.
Вы можете часто использовать размер шрифта, чтобы приблизить высоту - это то, что я делаю.
Но если вам действительно нужно больше точности, вот функция, которая проверяет пиксели текста, чтобы вычислить его высоту:
function measureTextHeight(fontSizeFace) {
// create a temp canvas
var width=1000;
var height=60;
var canvas=document.createElement("canvas");
canvas.width=width;
canvas.height=height;
var ctx=canvas.getContext("2d");
// Draw the entire a-z/A-Z alphabet in the canvas
var text="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
ctx.save();
ctx.font=fontSizeFace;
ctx.clearRect(0,0,width,height);
ctx.fillText(text, 0, 40);
ctx.restore();
// Get the pixel data from the canvas
var data = ctx.getImageData(0,0,width,height).data,
first = false,
last = false,
r = height,
c = 0;
// Find the last line with a non-transparent 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-transparent 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;
}
// error condition if we get here
return 0;
}
Просто чтобы опираться на предыдущие хорошие ответы здесь. Это даст высоту и ширину (у меня были некоторые проблемы с некоторыми символами юникода и measureText, это было единственное решение для некоторых символов).
function measureTextHeight(fontSizeFace, text) {
var width = 1500;
var height = 500;
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var ctx=canvas.getContext("2d");
ctx.save();
ctx.font=fontSizeFace;
ctx.clearRect(0,0,width,height);
ctx.fillText(text, parseInt(width * 0.1, 10), parseInt(height / 2, 10));
ctx.restore();
document.body.appendChild(canvas);
var data = ctx.getImageData(0,0,width,height).data;
var topMost = false;
var bottomMost = false;
var leftMost = false;
var rightMost = false;
for(var x=0; x<width; x++) {
for(var y=0; (y<height) && (!leftMost); y++) {
//console.log("x: %s y: %s index: %s", x,y, getAlphaIndexForCoordinates(x,y,width,height).toString() );
if(data[getAlphaIndexForCoordinates(x,y,width,height)] != 0) {
leftMost = x;
}
}
}
for(var y=0; y<height; y++) {
for(var x=0; (x<width) && (!topMost); x++) {
//console.log("x: %s y: %s index: %s", x,y, getAlphaIndexForCoordinates(x,y,width,height).toString() );
if(data[getAlphaIndexForCoordinates(x,y,width,height)] != 0) {
topMost = y;
}
}
}
for(var x=width-1; x>=0; x--) {
for(var y=height-1; (y>=0) && (!rightMost); y--) {
//console.log("x: %s y: %s index: %s", x,y, getAlphaIndexForCoordinates(x,y,width,height).toString() );
if(data[getAlphaIndexForCoordinates(x,y,width,height)] != 0) {
rightMost = x;
}
}
}
for(var y=height-1; y>=0; y--) {
for(var x=width-1; (x>=0) && (!bottomMost); x--) {
//console.log("x: %s y: %s index: %s", x,y, getAlphaIndexForCoordinates(x,y,width,height).toString() );
if(data[getAlphaIndexForCoordinates(x,y,width,height)] != 0) {
bottomMost = y;
}
}
}
return ({
width: (rightMost - leftMost) + 1
,height: (bottomMost - topMost) + 1
});
}
function getAlphaIndexForCoordinates(x,y,width,height) {
return (((width*4*y)+4*x)+3);
}
Хорошо, хорошо попробовал этот код, и мне пришлось немного изменить его, чтобы он работал.
это код после того, как мы нашли последнюю строку с непрозрачным пикселем.
так что, если кому-то это нужно просто замените Наслаждайтесь.
var blnFound = false;
var intCurrRow = 0;
// Find the first line with a non-transparent pixel
while(!blnFound && intCurrRow < last)
{
for(intCurrCol = 0; intCurrCol < width; intCurrCol++)
{
var intCurrDataIdx = intCurrRow * width * 4 + intCurrCol * 4 + 3;
if(data[intCurrDataIdx])
{
first = intCurrRow;
blnFound = true;
break;
}
}
// If we've got it then return the height
if (blnFound)
{
return last - first;
}
intCurrRow++;
}