テキストが使用可能な幅に収まらず、切り詰める必要がある場合、テキストの最後に省略記号があるキャンバスにテキストを描画することは可能ですか? ありがとう。
4 に答える
標準機能はありません。
必要に応じて、最適な文字列を計算する次の小さな関数を作成しました。
function fittingString(c, str, maxWidth) {
var width = c.measureText(str).width;
var ellipsis = '…';
var ellipsisWidth = c.measureText(ellipsis).width;
if (width<=maxWidth || width<=ellipsisWidth) {
return str;
} else {
var len = str.length;
while (width>=maxWidth-ellipsisWidth && len-->0) {
str = str.substring(0, len);
width = c.measureText(str).width;
}
return str+ellipsis;
}
}
はc
2D コンテキストです。
キャンバスのフォントやその他の描画パラメーターを設定した後、通常どおり文字列を描画できます。
c.fillText(fittingString(c, "A big string that will likely be truncated", 100), 50, 50);
多数のテキストを操作する場合、トップ投票の回答によりパフォーマンスの問題が発生します。
これは、文字列の適切な長さの検索を高速化するためにバイナリ検索を使用して適合されたバージョンです。
const binarySearch = ({ max, getValue, match }) => {
let min = 0;
while (min <= max) {
let guess = Math.floor((min + max) / 2);
const compareVal = getValue(guess);
if (compareVal === match) return guess;
if (compareVal < match) min = guess + 1;
else max = guess - 1;
}
return max;
};
const fitString = (
ctx,
str,
maxWidth,
) => {
let width = ctx.measureText(str).width;
const ellipsis = '…';
const ellipsisWidth = ctx.measureText(ellipsis).width;
if (width <= maxWidth || width <= ellipsisWidth) {
return str;
}
const index = binarySearch({
max: str.length,
getValue: guess => ctx.measureText(str.substring(0, guess)).width,
match: maxWidth - ellipsisWidth,
});
return str.substring(0, index) + ellipsis;
};
複数行のテキストレンダリングをサポートしていないブラウザ関連のテクノロジがいくつかあります。
そのため、私はこの問題に対処するために小さなライブラリを開発しました(とりわけ)。ライブラリは、文字レベルのテキストレンダリングをモデル化して実行するためのオブジェクトを提供します。これはあなたが必要なことをするはずです:
スクリーンショット、チュートリアル、およびダウンロードリンクについては、http://www.samuelrossille.com/home/jstextを参照してください。
html5 の drawText にはそのようなものはなく、実装が少し複雑になります。希望のサイズに収まるまで、ストリングをトリミングするループが必要です。テキストが回転されていない場合、またはその他の特別な効果がある場合は、絶対位置を持つ通常の div と次の CSS スタイルを使用することをお勧めします。
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
white-space: nowrap;
width: 100%;