Как вы можете найти высоту текста на холсте HTML?

Спецификация имеет функцию context.measureText(text), которая сообщит вам, сколько ширины потребуется для печати этого текста, но я не могу найти способ узнать, насколько он высок. Я знаю это на основе шрифта, но я не знаю, чтобы преобразовать строку шрифта в высоту текста.

Ответ 1

UPDATE - для примера этой работы я использовал эту технику в редакторе GetTextMetric. Это необходимо, если вы хотите выполнить текстовый запуск текста с пробелами в разных шрифтах/размерах.

Big Text on canvas with metric lines

Вышеописанное изображение было сгенерировано на холсте в 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');

Ответ 2

Спецификация canvas не дает нам метода измерения высоты строки. Тем не менее, вы можете установить размер текста в пикселях, и вы обычно можете определить, что вертикальные границы относительно легко.

Если вам нужно что-то более точное, вы можете наложить текст на холст, а затем получить пиксельные данные и выяснить, сколько пикселей используется по вертикали. Это было бы относительно просто, но не очень эффективно. Вы могли бы сделать что-то вроде этого (оно работает, но рисует какой-то текст на вашем холсте, который вы хотите удалить):

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);

Для Bespin они подделывают высоту, измеряя ширину нижнего регистра "m"... Я не знаю, как это используется, и я бы не рекомендовал этот метод. Вот соответствующий метод 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; }
    }
};

Ответ 3

Вы можете получить очень близкое приближение к вертикальной высоте, проверив длину капитала M.

ctx.font='bold 10px Arial';

lineHeight=ctx.measureText('M').width;

Ответ 4

EDIT: Используете ли вы преобразования холста?. Если это так, вам придется отслеживать матрицу преобразования. Следующий метод должен измерять высоту текста с начальным преобразованием.

EDIT # 2: Как ни странно, приведенный ниже код не дает правильных ответов, когда я запускаю его на этой странице StackOverflow; вполне возможно, что наличие некоторых правил стиля может нарушить эту функцию.

Холст использует шрифты, как определено CSS, поэтому в теории мы можем просто добавить в документ соответствующий стиль текста и измерить его высоту. Я думаю, что это значительно проще, чем отрисовка текста, а затем проверка пиксельных данных, и он также должен учитывать восходящие и десендерные. Проверьте следующее:

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.");
  }
}

Вам нужно убедиться, что вы правильно набрали стиль шрифта на элементе DOM, который вы измеряете высоту, но это довольно просто; действительно вы должны использовать что-то вроде

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.
*/

Ответ 5

Браузеры начинают поддерживать расширенные текстовые метрики, которые сделают эту задачу тривиальной, когда она широко поддерживается:

let metrics = ctx.measureText(text);
let fontHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
let actualHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;

fontHeight возвращает вам высоту ограничительной рамки, которая является постоянной независимо от отображаемой строки. actualHeight относится к отображаемой строке.

Spec: https://www.w3.org/TR/2012/CR-2dcontext-20121217/#dom-textmetrics-fontboundingboxascent и разделы чуть ниже него.

Статус поддержки (20 августа 2017 года):

Ответ 6

Я не знаю точно, но я помню, что Дион Алмаер сказал что-то об этом в презентации Google IO о Mozilla Bespin. Это было что-то вроде переворачивания буквы М, а затем измерения ее ширины. Но я могу ошибаться.

Ответ 7

Как указывает JJ Stiff, вы можете добавить свой текст в диапазон, а затем измерить смещениеHeight диапазона.

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);

Как показано на HTML5Rocks

Ответ 8

Разве высота текста в пикселях не равна размеру шрифта (в очках), если вы определяете шрифт, используя context.font?

Ответ 9

Просто добавьте к Daniel ответ (это здорово! и абсолютно правильно!), версия без 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 try to avoid any potential glitches in various browsers
    // by making it 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];
}

Я только что проверил вышеописанный код и отлично поработал на последних версиях Chrome, FF и Safari на Mac.

EDIT: Я добавил размер шрифта, а также тестировал с помощью webfont вместо системного шрифта - работает потрясающе.

Ответ 10

Я решил эту проблему, используя пиксельные манипуляции.

Вот графический ответ:

Вот код:

    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;

}

Ответ 11

Я пишу эмулятор терминала, поэтому мне нужно рисовать прямоугольники вокруг символов.

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

Очевидно, что если вам требуется точное количество места, которое занимает персонаж, это не поможет. Но это даст вам хорошее приближение для определенных целей.

Ответ 12

Я реализовал красивую библиотеку для измерения точной высоты и ширины текста с помощью HTML-холста. Это должно делать то, что вы хотите.

https://github.com/ChrisBellew/text-measurer.js

Ответ 13

Вот простая функция. Никакой библиотеки не требуется.

Я написал эту функцию, чтобы получить верхнюю и нижнюю границы относительно базовой линии. Если для параметра textBaseline установлено значение alphabetic. Он делает это, создавая еще один холст, а затем рисует там, а затем находит самый верхний и нижний самый непустой пиксель. И это верхняя и нижняя границы. Он возвращает его как относительный, поэтому, если высота 20px, и нет ничего ниже базовой линии, то верхняя граница -20.

Вы должны указать на него символы. В противном случае это даст вам 0 высоты и 0 ширины, очевидно.

Использование:

alert(measureHeight('40px serif', 40, 'rg').height)

Вот функция:

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 и height являются полезными вещами в возвращаемом объекте.

Вот пример использования:

<!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>

Ответ 14

один ответ строки

var height = parseInt(ctx.font) * 1.2; 

CSS "line-height: normal" находится между 1 и 1.2

прочитайте здесь для получения дополнительной информации

Ответ 16

Прежде всего, вам нужно установить высоту размера шрифта, а затем в соответствии со значением высоты шрифта, чтобы определить текущую высоту вашего текста, сколько строк кросс-текста, разумеется, того же высота шрифта должна накапливаться, если текст не превышает наибольшее текстовое поле "Высота", все показывают, иначе отображается только текст в тексте поля. Высоким значениям требуется ваше собственное определение. Чем больше заданная высота, тем больше высота текста, который нужно отобразить и перехватить.

После того, как эффект обработан ()

Перед обработкой эффекта ( нерешенный)

  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;};

Ответ 17

Я обнаружил, что JUST FOR ARIAL самый простой, быстрый и точный способ определить высоту ограничительной рамки - это использовать ширину определенных букв. Если вы планируете использовать определенный шрифт, не позволяя пользователю выбирать другой, вы можете провести небольшое исследование, чтобы найти правильную букву, которая выполняет работу для этого шрифта.

<!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>

Ответ 18

установка размера шрифта может быть непрактична, поскольку установка

ctx.font = ''

будет использовать значение, определенное CSS, а также любые встроенные теги шрифтов. Если вы используете шрифт CSS, вы не представляете, какая высота является программным способом, используя метод measureText, который очень близок. На другой ноте, однако, IE8 возвращает ширину и высоту.

Ответ 19

Это то, что я сделал, основываясь на некоторых других ответах здесь:

function measureText(text, font) {
	const span = document.createElement('span');
	span.appendChild(document.createTextNode(text));
	Object.assign(span.style, {
		font: font,
		margin: '0',
		padding: '0',
		border: '0',
		whiteSpace: 'nowrap'
	});
	document.body.appendChild(span);
	const {width, height} = span.getBoundingClientRect();
	span.remove();
	return {width, height};
}

var font = "italic 100px Georgia";
var text = "abc this is a test";
console.log(measureText(text, font));

Ответ 20

Примерное решение:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "100px Arial";
var txt = "Hello guys!"
var wt = ctx.measureText(txt).width;
var height = wt / txt.length;

Это будет точный результат в моноширинном шрифте.

Ответ 21

Это безумие... Высота текста - это размер шрифта. Разве никто из вас не читал документацию?

context.font = "22px arial";

это установит высоту 22px.

единственная причина, по которой есть..

context.measureText(string).width

заключается в том, что ширина строки не может быть определена, если она не знает строку, в которой вы хотите ширину, но для всех строк, нарисованных с помощью шрифта.. высота будет 22px.

если вы используете другое измерение, чем px, тогда высота будет по-прежнему одинаковой, но с этим измерением, поэтому, самое большее, что вам нужно будет сделать, это преобразовать измерение.

Ответ 22

В нормальных ситуациях должно работать следующее:

var can = CanvasElement.getContext('2d');          //get context
var lineHeight = /[0-9]+(?=pt|px)/.exec(can.font); //get height from font variable