JavaScript を使用して文字列の幅を計算したいのですが、等幅フォントを使用せずにこれが可能ですか?
組み込まれていない場合、私の唯一のアイデアは、各文字の幅のテーブルを作成することですが、これは特にサポートするにはかなり不合理です。ユニコードさまざまな文字サイズ(そしてすべてのブラウザ)
ベストアンサー1
HTML 5では、Canvas.measureText メソッド(詳しい説明ここ)。
/**
* Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
*
* @param {String} text The text to be rendered.
* @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
*
* @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
*/
function getTextWidth(text, font) {
// re-use canvas object for better performance
const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
const context = canvas.getContext("2d");
context.font = font;
const metrics = context.measureText(text);
return metrics.width;
}
function getCssStyle(element, prop) {
return window.getComputedStyle(element, null).getPropertyValue(prop);
}
function getCanvasFont(el = document.body) {
const fontWeight = getCssStyle(el, 'font-weight') || 'normal';
const fontSize = getCssStyle(el, 'font-size') || '16px';
const fontFamily = getCssStyle(el, 'font-family') || 'Times New Roman';
return `${fontWeight} ${fontSize} ${fontFamily}`;
}
console.log(getTextWidth("hello there!", "bold 12pt arial")); // close to 86
特定の要素のフォント サイズを使用したい場合はmyEl
、ユーティリティ関数を使用できますgetCanvasFont
。
const fontSize = getTextWidth(text, getCanvasFont(myEl));
// do something with fontSize here...
説明: このgetCanvasFontSize
関数は、いくつかの要素(デフォルトではbody
)のフォントを受け取り、それをContext.font プロパティもちろん、要素は使用する前にまず DOM に追加する必要があります。そうしないと、誤った値が返されます。
その他のメモ
このアプローチには、次のようないくつかの利点があります。
- DOM などのグローバル状態を変更しないため、他の (DOM ベースの) メソッドよりも簡潔で安全です。
- さらにカスタマイズするにはキャンバスのテキストプロパティをさらに変更する
textAlign
、などtextBaseline
。
注意: DOMにテキストを追加するときは、次の点も考慮してください。パディング、マージン、ボーダー。
注 2: 一部のブラウザでは、この方法ではサブピクセル精度が得られます (結果は浮動小数点数)。他のブラウザでは得られません (結果は int のみ)。不整合を回避するために、結果に対してMath.floor
(またはMath.ceil
) を実行することをお勧めします。DOM ベースの方法ではサブピクセル精度が得られないため、この方法は他の方法よりもさらに精度が高くなります。
によるとこのjsperf(コメントの投稿者に感謝します)、DOM ベースの方法にキャッシュが追加され、Firefox を使用していない場合は、Canvas 方法とDOM ベースの方法はほぼ同じくらい高速です。Firefox では、何らかの理由で、このCanvas 方法の方がDOM ベースの方法よりもはるかに高速です(2014 年 9 月現在)。
パフォーマンス
このバイオリンこのCanvasメソッドを、Bob MonteverdeのDOMベースの方法結果の精度を分析および比較することができます。