この記事では、キャンバス描画プロセス中のdrawTextの行折り返し問題を解決する方法を紹介します。まず、キャンバス上にテキストを描画するときに誰もが遭遇する問題を見てみましょう。
透明な境界線のある 150*100 のキャンバス
<canvas id=canvas style=border:solid 1px darkgoldenrod width=200px height=100px></canvas>
まず、fillText() メソッドを見てみましょう。ストロークText() メソッドも同様に機能します。
var c=document.getElementById(canvas); var ctx=c.getContext(2d); ctx.fillStyle=#E992B9;ctx.lineWidth=1;var str = 人生があなたを騙しても、悲しまないでください。ありがとうございます!ctx.fillText(str,0,20);
固定幅のキャンバスに単語が多すぎると、fillText() が自動的に折り返されないことがわかります。キャンバス自体の幅を増やすことはできますが、これは問題を解決する根本的な方法ではありません。以前、基本的な Canvas API を紹介したときに、 context.measureText(text)
この関数は、文字列の長さを計算するために、フォントの幅と高さを測定することができます。基本的に、この行の折り返しの問題は解決できます。
具体的な実装方法を見てみましょう。
var c=document.getElementById(canvas); var ctx=c.getContext(2d); ctx.fillStyle=#E992B9;ctx.lineWidth=1; 人生があなたを騙しても、悲しまないでください。ありがとうございます!var lineWidth = 0;var CanvasWidth = c.width;//キャンバスの幅を計算します var initHeight=15;//キャンバスの上部からの描画フォントの初期の高さ var lastSubStrIndex= 0;毎回インターセプトされる文字列 Index of for(let i=0;i<str.length;i++){ lineWidth+=ctx.measureText(str[i]).width; if(lineWidth>canvasWidth){ ctx.fillText(str.substring(lastSubStrIndex,i),0,initHeight);//切られた部分を描画 initHeight+=20;//20 はフォントの高さです lineWidth=0;私; } if(i==str.length-1){//残りの部分を描画 ctx.fillText(str.substring(lastSubStrIndex,i+1),0,initHeight);
レンダリングを参照してください。
アルゴリズム: 文字列 str 内の各文字の幅と lineWidth の合計を計算します。それがキャンバスの幅より大きい場合は、描画のためにこの部分をインターセプトし、次に lineWidth をリセットし、インターセプトが開始された最後のインデックスを保存します。ループ変数 i が最後の文字の場合、残りの部分を直接描画します。
次に、これをメソッドにカプセル化して、後で直接呼び出せるようにします。
/*str: 描画する文字列 Canvas: キャンバスオブジェクト initX: 描画文字列の開始 x 座標 initY: 描画文字列の開始 y 座標 lineHeight: ワードラインの高さ、値は自分で定義できます */function CanvasTextAutoLine(str, Canvas, initX,initY,lineHeight){ var ctx = Canvas.getContext(2d); var lineWidth = 0; lastSubStrIndex= 0; for(let i=0;i<str.length;i++){ lineWidth+=ctx.measureText(str[i]).width; if(lineWidth>canvasWidth-initX){//問題を防ぐために initX を減算します。境界あり ctx.fillText(str.substring(lastSubStrIndex,i),initX,initY); initY+=lineHeight=0; lastSubStrIndex=i; } if(i==str.length-1){ ctx.fillText(str.substring(lastSubStrIndex,i+1),initX,initY);
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。また、VeVb Wulin Network をご支援いただければ幸いです。