仕様にはcontext.measureText(text)関数があり、そのテキストを印刷するために必要な幅を教えてくれますが、それがどのくらいの高さであるかを見つける方法が見つかりません。フォントに基づいていることは知っていますが、フォント文字列をテキストの高さに変換する方法がわかりません。
M̶̢̹̝͖̦̖̭͕̭̣͆̃̀̅̒̊͌̿ͅ
これは非常に難しい問題なので、一般的なケースで解決してください。
仕様にはcontext.measureText(text)関数があり、そのテキストを印刷するために必要な幅を教えてくれますが、それがどのくらいの高さであるかを見つける方法が見つかりません。フォントに基づいていることは知っていますが、フォント文字列をテキストの高さに変換する方法がわかりません。
M̶̢̹̝͖̦̖̭͕̭̣͆̃̀̅̒̊͌̿ͅ
これは非常に難しい問題なので、一般的なケースで解決してください。
回答:
更新 -この作業の例として、Carotaエディターでこの手法を使用しました。
ellisbbenの回答に続き、ベースラインからの上昇と下降を取得する拡張バージョンがあります。つまり、Win32のGetTextMetric API 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');
getTextHeight()
までvar text = $('<span>Hg</span>').css({ 'font-family': fontName, 'font-size' : fontSize });
、つまりはサイズを個別に追加します。
<div></div>
するために<div style="white-space : nowrap;"></div>
非常に長い文字列を処理するために
大文字Mの長さを確認することにより、垂直方向の高さを非常に正確に近似できます。
ctx.font='bold 10px Arial';
lineHeight=ctx.measureText('M').width;
キャンバスの仕様では、文字列の高さを測定する方法を提供していません。ただし、テキストのサイズをピクセル単位で設定でき、通常は垂直境界が比較的簡単にわかるようになります。
より正確なものが必要な場合は、キャンバスにテキストを投げてピクセルデータを取得し、垂直方向に使用されているピクセル数を把握できます。これは比較的単純ですが、あまり効率的ではありません。あなたはこのようなことをすることができます(それは機能しますが、あなたが削除したいキャンバスにテキストを描画します):
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」の幅を測定することで高さを偽っています...これがどのように使用されるのかわかりません。この方法はお勧めしません。関連するベスピン法は次のとおりです。
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; }
}
};
em
1つのemがM
デフォルトのフォントサイズの文字の高さに等しい相対フォント測定です。
ブラウザーは高度なテキストメトリックをサポートし始めており、広くサポートされている場合、このタスクは簡単になります。
let metrics = ctx.measureText(text);
let fontHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
let actualHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
fontHeight
レンダリングされる文字列に関係なく一定であるバウンディングボックスの高さを取得します。actualHeight
レンダリングされる文字列に固有です。
仕様:https : //www.w3.org/TR/2012/CR-2dcontext-20121217/#dom-textmetrics-fontboundingboxascentとそのすぐ下のセクション。
サポート状況(2017年8月20日):
編集:キャンバス変換を使用していますか? その場合、変換行列を追跡する必要があります。次のメソッドは、最初の変換でテキストの高さを測定する必要があります。
編集#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.
*/
context.fontを使用してフォントを定義する場合、ピクセル単位のテキストの高さはフォントサイズ(pts)と等しくありませんか?
JJ Stiffが提案するように、テキストをスパンに追加してから、スパンのoffsetHeightを測定できます。
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に示されているように
ダニエルの回答に追加するだけで(これはすばらしいことであり、絶対に正しい!)、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's try to avoid any potential glitches in various browsers
// by making it's 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、MacのSafariで問題なく動作しました。
編集:私はフォントサイズも追加し、システムフォントの代わりにwebfontでテストしました-素晴らしい作品です。
私はこの問題を解決しました-ピクセル操作を使用して。
ここにグラフィカルな答えがあります:
ここにコードがあります:
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;
}
私は端末エミュレーターを書いているので、文字の周りに長方形を描く必要がありました。
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
キャラクターが占める正確なスペースが必要な場合は、明らかに役に立ちません。しかし、それはあなたに特定の用途のための良い近似を与えるでしょう。
HTMLキャンバスを使用してテキストの正確な高さと幅を測定するための素晴らしいライブラリを実装しました。これはあなたが望むことをするはずです。
これは簡単な関数です。ライブラリは必要ありません。
この関数は、ベースラインを基準にして上限と下限を取得するために作成しました。textBaseline
がに設定されてalphabetic
いる場合。これは、別のキャンバスを作成してそこに描画し、一番上と一番下の空白でないピクセルを見つけます。そして、それが上限と下限です。これは相対値として返されるため、高さが20pxで、ベースラインの下に何もない場合、上限はになり-20
ます。
文字を指定する必要があります。それ以外の場合は、明らかに高さと幅が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>
relativeBot
そしてrelativeTop
あなたはここで、この画像の中に見えるものです。
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text
TextMetricsには幅のみがあり、高さはないのは面白いことです。
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#textmetrics
この例のようにスパンを使用できますか?
http://mudcu.be/journal/2011/01/html5-typographic-metrics/#alignFix
これは私がここでの他のいくつかの答えに基づいてやったことです:
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));
まず、フォントサイズの高さを設定する必要があります。次に、フォントの高さの値に応じて、テキストの現在の高さを決定します。もちろん、クロステキストの行数は、同じです。テキストが最大のテキストボックスの高さを超えない場合、フォントを蓄積する必要があります。すべて表示します。それ以外の場合は、ボックステキスト内のテキストのみを表示します。高い値には独自の定義が必要です。プリセットの高さが大きいほど、表示およびインターセプトする必要があるテキストの高さが大きくなります。
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;};
私は、ことがわかっJUST FOR ARIAL境界ボックスの高さを見つけるための最も簡単、最速とaccuratest方法は、特定の文字の幅を使用することです。ユーザーが別のフォントを選択することを許可せずに特定のフォントを使用する場合は、少し調べて、そのフォントに適した文字を見つけることができます。
<!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>
ただし、フォントサイズの設定は実用的でない場合があります。
ctx.font = ''
CSSで定義されたものと埋め込みフォントタグを使用します。CSSフォントを使用している場合、プログラム的な方法からの高さはわかりませんが、measureTextメソッドを使用しているため、近視眼的です。ただし、IE8は幅と高さを返します。
これは、1)マルチラインテキストでも同様に機能します2)IE9でも機能します!
<div class="measureText" id="measureText">
</div>
.measureText {
margin: 0;
padding: 0;
border: 0;
font-family: Arial;
position: fixed;
visibility: hidden;
height: auto;
width: auto;
white-space: pre-wrap;
line-height: 100%;
}
function getTextFieldMeasure(fontSize, value) {
const div = document.getElementById("measureText");
// returns wrong result for multiline text with last line empty
let arr = value.split('\n');
if (arr[arr.length-1].length == 0) {
value += '.';
}
div.innerText = value;
div.style['font-size']= fontSize + "px";
let rect = div.getBoundingClientRect();
return {width: rect.width, height: rect.height};
};
私はこれが古い回答の質問であることを知っていますが、将来の参考のために、短い、最小限の、JSのみ(jqueryなし)のソリューションを追加したいと思います。
var measureTextHeight = function(fontFamily, fontSize)
{
var text = document.createElement('span');
text.style.fontFamily = fontFamily;
text.style.fontSize = fontSize + "px";
text.textContent = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
document.body.appendChild(text);
var result = text.getBoundingClientRect().height;
document.body.removeChild(text);
return result;
};
通常の状況では、以下が機能するはずです。
var can = CanvasElement.getContext('2d'); //get context
var lineHeight = /[0-9]+(?=pt|px)/.exec(can.font); //get height from font variable
これはマッドです...テキストの高さはフォントサイズです。ドキュメントを読んだ人はいませんか?
context.font = "22px arial";
これにより、高さが22pxに設定されます。
唯一の理由は..
context.measureText(string).width
これは、フォントで描画されたすべての文字列に対して、幅が必要な文字列がわかっている場合を除いて、文字列の幅を決定できないためです。高さは22pxになります。
px以外の測定値を使用する場合、高さは同じですが、その測定値であるため、せいぜい測定を変換するだけで済みます。