Webフォント、HTML5Canvasで使うときの注意^^
Webフォントを使うと、ブラウザやOSが違っても同じ文字表現が出来るので便利だ。
だけど、結構な大きさのファイルをダウンロードさせる必要があるため(10MByte以上)中々導入となると、ちょっとねえ・・って二の足を踏んでしまう。
なので、これまであまりWebフォントを使わずに、なるべく内部のフォントを使っていたわけだが、今回ios,android,pcでそれぞれ表現させると、内部のフォントが結構ちがっていたこと、Webフォントを使うと、結構かっこよく見えたため、今回はWebフォントを採用しようと思った次第。
・・・・・・・・・・・・・・・・・・・・・・・
だけど、問題が勃発。
と言うのも、Canvasを使っている部分が主であり、このWebフォントをCanvasで利用したいと思っていたのだけど、画面を表示させたしょっぱなだけ、何故かWebフォントが使われないと言う、問題が発生していた。
と言うのも、PCでは普通に問題なく動くことから、発見が遅れたと言うか、実際にiosの実機でMobileSafariから起動させると、Canvasに対して、最初の表示文字がWebフォントを使われず、次に表示されるときからWebフォントが対応されると言う状況が発生したわけで、最初?何だろうか?画面がおかしいって感じで思った次第。
・・・・・・
結果論から言うと、CanvasでWebフォントを読もうとすると、非同期で実行されるため、だからCanvasの最初の表示では、文字に対してWebフォントは利用できない状況となり、内部のフォントが利用されていたと言うことである。
たぶん別途最初にCanvas上に対象のフォントを読み込み処理すれば、問題なくWebフォントが反映されると思うが、もっと簡単に対応できるものはないのか?って思い探したが、まあそんなものはなく、結果的に以下URLのサイトを参考に作った次第。
var ERROR_COUNT = 100; var CHECK_TIME = 50; // 指定されたWebフォントをCanvas向けにロード. var loadWebFont = function(name,bold,successCall,errorCall) { //webフォントのロード状況を確認する var c1 = document.createElement("canvas"); var c2 = c1.cloneNode(false); var ctx1 = c1.getContext("2d"); var ctx2 = c2.getContext("2d"); var boldText = (bold?"bold ":""); ctx1.font = " " + boldText + "15px "+name+", serif"; ctx2.font = " " + boldText + "15px serif"; var text = "load web font test."; //テキスト幅を比較する //webフォントが利用可能となると,フォント幅が一致する. var isLoaded = function(){ var tm1 = ctx1.measureText(text); var tm2 = ctx2.measureText(text); return tm1.width != tm2.width; } var exitLoad var cnt = 0; var tryDraw = function(){ if(!isLoaded() && cnt < ERROR_COUNT){ cnt++; setTimeout(tryDraw, CHECK_TIME); } else if(cnt >= ERROR_COUNT) { if(typeof(errorCall) == "function") { errorCall(); } } else { if(typeof(successCall) == "function") { successCall(); } } } tryDraw(); } // Webフォント読み込み成功処理. var viewSuccessWebFont = function(name,bold) { var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "white"; var boldText = (bold?"bold ":""); ctx.font = " " + boldText + "15px "+name+", serif"; ctx.fillText(" ... success", 0, 0); document.body.appendChild(canvas); } // こんな感じで利用する。 loadWebFont("\'Noto Sans JP\'",true,function() { // WebFont読み込み成功. viewSuccessWebFont("\'Noto Sans JP\'",true); });