JavaScriptにて次を実現したい。
- 複数行のテキストがある
- それをCanvas要素に描画したい
- ただし改行をしながら
Canvasにはテキスト描画APIがあるけど……
複数行描画するようなメソッドはありません。
少しだけ工夫が必要になってきます。
そこでJSで改行込みでテキスト描画する方法、
その方法とかJavaScriptコード例などを紹介します。
初めに複数行を文字列配列に分割(split)する
下準備として複数行を分割します。
改行コードでsplitすればいいだけです。
▼ 例えば次のように複数行テキスト分割
1 2 3 4 5 6 7 8 9 10 11 |
/// 描画したいテキスト const text = ` Doe, a deer, a female deer Ray, a drop of golden sun Me, a name I call myself `.trim() /// 文字列配列に変換 const lines = text.split(/\r?\n/) console.log(lines) |
▼ コンソール出力結果
1 2 3 4 5 |
(3) [ 'Doe, a deer, a female deer', 'Ray, a drop of golden sun', 'Me, a name I call myself' ] |
ここまでが改行しながらテキスト描画する下準備
改行は
\n /
\r /
\r\n のどれかだから、
それを正規表現としてsplitしているだけです。
テキストの幅・高さに合わせてcanvasリサイズ
次にテキスト全体にcanvas要素をリサイズさせます。
※ この部分はなくてもOK
そのために以下の手順を踏むことにしました
- テキスト行の最大幅を求める
- テキスト高さを求める
- それに合わせてcanvasをリサイズ
具体的には次のようなコードです。
▼ こういうコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/// 描画対象のcanvas要素 const canvas = document.getElementById('canvas') const fontSize = 24 let maxWidth=0, maxHeight=0 lines.forEach((line, i) => { /// 仮想的なspna要素を作成 const span = document.createElement('span') /// テキスト行を代入 span.innerHTML = line /// フォントサイズ指定 span.style.fontSize = fontSize+'px' /// 仮想要素をbodyに突っ込んでサイズ計算 document.body.appendChild(span) maxWidth = Math.max(maxWidth, span.offsetWidth) maxHeight += maxHeight,span.offsetHeight document.body.removeChild(span) }) /// canvas要素を最大幅・高さに合わせる canvas.width = maxWidth canvas.height = maxHeight |
何をしているかはコメントを参照
仮想的なspan要素にテキストの各行を代入し、それをbodyに一時的に突っ込んで span.offsetWidth / span.offsetHeight から各行の最大幅・高さを求めてます。
この部分はcanvasにテキストをピッタリ納めるため
もし必要ないなら上記処理はいりません。
改行しながらテキスト行をcanvasに描画
最後に改行しながらテキスト描画していきます。
▼ このようなコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/// canvasコンテキスト const ctx = canvas.getContext("2d") const lineHeight = maxHeight/lines.length let x = 0, y = fontSize lines.forEach((line, i) => { /// フォント指定 ctx.font = fontSize+"px Arial" /// 計算した位置に行を描画 ctx.fillText(line, x, y) /// canvas上で原始的に改行する y += maxHeight }) |
各変数は先ほどのコードででてきた変数と同じです。
テキスト描画には c tx.fillText(line, x, y) を使うだけなので、改行するために y += maxHeight として描画位置を変更しています
テキスト改行描画する全体のJSコード例
最後にここまでの全体コードを載せておきます。
▼ 分かりやすく関数化してみた
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
function drawText(canvas, text){ /// canvasコンテキスト const ctx = canvas.getContext("2d") /// 分割された文字列 const lines = text.split(/\r?\n/) /// フォントサイズ(仮) const fontSize = 24 let maxWidth=0, maxHeight=0 lines.forEach((line, i) => { /// 仮想的なspna要素を作成 const span = document.createElement('span') /// テキスト行を代入 span.innerHTML = line /// フォントサイズ指定 span.style.fontSize = fontSize+'px' /// 仮想要素をbodyに突っ込んでサイズ計算 document.body.appendChild(span) maxWidth = Math.max(maxWidth, span.offsetWidth) maxHeight += span.offsetHeight document.body.removeChild(span) }) /// canvas要素を最大幅・高さに合わせる canvas.width = maxWidth canvas.height = maxHeight /// 改行しながらテキスト描画 const lineHeight = maxHeight/lines.length let x = 0, y = fontSize lines.forEach((line, i) => { /// フォント指定 ctx.font = fontSize+"px Arial" /// 計算した位置に行を描画 ctx.fillText(line, x, y) /// canvas上で原始的に改行する y += lineHeight }) } |
▼ 例えば次のように使える
1 2 3 4 5 6 7 8 9 10 |
/// canvas要素 const canvas = document.getElementById('canvas') /// 描画したいテキスト const text = ` Doe, a deer, a female deer Ray, a drop of golden sun Me, a name I call myself `.trim() /// 改行しながらテキスト描画 drawText(canvas, text) |
こういった風に複数行描画が可能
以上、JavaScriptでCanvasに複数行描画でした。
少しだけ工夫が必要なことに注意です。