習うより慣れろの意気込みで、やさしいものから実用的なプログラミングを目ざしました。現在日付を出力、現在時刻を出力、一週間のゴミ出し作業、一週間の仕事、著作権消滅童謡の演奏と徐々に機能の高いプログラミングに挑戦してきました。
コピー&ペーストにより、○○.htmlを作成してJavaScriptを実行すれば、おおむね結果が得られるものばかりです。思い通りの結果が得られない場合は、ブラウザを変えたり、バージョンを上げるなどの措置で解決することがあります。
忙しい方は末尾の実行例で❶~⓰の番号をクリックしてください。
今回の挑戦
今回は、16個の画像を集合して作った大きな画像から、一つを切り取って指定された場所に描画します。
個々の画像は表示位置が固定されているので、神経衰弱のゲームを作るときに応用することができるでしょう。
神経衰弱は52枚のカードを用意しますが、52個をまとめて一つの画像にするには、画像容量があまりにも大き過ぎます。
同一マーク13個を一つにまとめればちょうど、程よい大きさになることでしょう。
画像の作り方
個々の画像をまとめて一枚の大きな画像を作るには、規則正しい書式にすると便利です。
それには個々の画像をサイズの等しい正方形、長方形にし、i行j列の碁盤の目のように並べます。詳しくは習うより慣れろprogramingEの画像形式が参考になります。
1.FotoFlexer
2.SUMO Paint
3.PIXLR
4.PIXER.US
5.PicMagick
6.GIMP
7.Paint.net
8.INKSCAPE
9.Picasa
10.Seashore
画像のトリミング表示方法
画像の一部を切り抜いて表示することをトリミングと呼んでいます。JavaScriptの組み込み関数にはトリミング機能が用意されています。集合写真で両端に写ったグループ外のメンバーを削除したり、部品素材集から気に入った画像を取り出すときに利用します。drawImage関数の利用例を示します。
処理の概要
方針
習うより慣れろprogramingEにおいて、16景表示レイアウトはあらかじめ作成した画像イメージを表示しましたが、ここではbeginPath, moveTo, lineTo, stroke関数を用いて動的に描画しました。事前に準備した画像ファイルを使えばコードサイズは小さくなりますが、動的表示法は選択肢が広がります。
処理概要
タッチやクリックイベントを処理する関数を取り付けて、タッチされた位置を0~15に変換してその番号に割り当てられた画像を1回だけ表示します。
MouseEventインターフェイスは、ポインティングデバイス (マウスなど) によるユーザの対話によって発生したイベントを捕捉することができます。その中でclickイベントはボタンが押され、そして離されたときに発生します。
イベントが発生した時に見逃すことなく処理されるように動作する仕組み《イベントドリブン機構》をJavaScript制御システムが用意しています。
コードの解説
①1行、htmlタグの宣言。
②5行、丸囲み数字の定義。
③6行、処理済みフラグに使用。
④7~8行、描画位置の調整用。
⑤9行、コンテキストを退避する。
⑥10~11行、16景画像を早めにロードする。
⑦12行、ロード時に起動する関数を定義する。
⑧13行、描画コンテキストを取得する。
⑨14行、有効なコンテキストを初回に実行する。
⑩16~25行、横縦のグリッド線と目盛を表示。
⑪26~32行、16景番号を表示。
⑫34行、canvasクリックイベントを取り付ける。
⑬35~37行、カーソル位置から相対値を求める。
⑭40~42行、相対値を0~15の通算番号に変換。
⑮43行、初回のみ処理する。
⑯45行、通算番号から適切な16景画像を表示。
⑰54行、ロード時に起動する関数を設定する。
⑱55~56行、ガイドメッセージを定義する。
⑲57行、canvasエリアを定義する。
サンプルコード
<html> <head> <script language="JavaScript"> //① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ const num = "\u2776\u2777\u2778\u2779\u277A\u277B\u277C\u277D\u277E\u277F\u24EB\u24EC\u24ED\u24EE\u24EF\u24F0"; var out = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //描画済みフラッグ, Tiny-F.html const BX = 10; //描画位置規定値-x const BY = 10; //描画位置規定値-y var ctx = 0; //コンテキストを退避する var img16Fl = new Image(); //16景 img16Fl.src = "https://aidesign.lolipop.jp/wp-content/uploads/2016/08/16image.png"; //トンボ16景 function starting(){ //ロード時に起動する関数 var canvas = document.getElementById('tutorial'); //描画コンテキストの取得 if (canvas.getContext && (ctx==0)){//再試行は禁止 ctx = canvas.getContext('2d'); //描画コンテキスト for(var i=0; i<5; ++i){ //0 1 2 3 4 ctx.beginPath(); if((i%4)==0) ctx.lineWidth = 4;//0 4 else ctx.lineWidth = 1;//1 2 3 ctx.moveTo(BX, BY+i*120); ctx.lineTo(BX+640, BY+i*120); //x-axis ctx.moveTo(BX+i*160, BY); ctx.lineTo(BX+i*160, BY+480); //y-axis ctx.stroke(); ctx.fillText((i*160).toString(10), BX+i*160, BY+500); //x-measure ctx.fillText((i*120).toString(10), BX+647, BY+i*120+3); //y-measure } for(i=0; i<16; ++i){ //16景番号を表示する var x = i % 4; //x方向位置 var y = Math.floor(i / 4); //y方向位置 ctx.font = "48px 'MS Pゴシック'"; ctx.fillStyle = "blue"; ctx.fillText(num[i], BX+x*160+59, BY+y*120+75);//16景番号を表示 } canvas.addEventListener('click', function(e){ //canvasイベント関数を定義 var button = e.target.getBoundingClientRect(); var mouseX = e.clientX - button.left - BX; //160 var mouseY = e.clientY - button.top - BY; //120 x = Math.floor(mouseX / 160); //4 y = Math.floor(mouseY / 120); //4 if(x>=0 && x<=3){ //16景、表示領域外は無効 if(y>=0 && y<=3){ i = y * 4 + x; //通算番号に変換 if(out[i]==0){ //初回のみ、有効 out[i] = 1; //処理済みにする ctx.drawImage(img16Fl, 160*x,120*y, 160,120, 160*x+BX,120*y+BY, 160,120);//16景画像 } } } }, false); } } </script> </head> <body onLoad="starting();"> <font size=4 color='maroon'>16画像描画 Tiny-F.html, Ver 0.01, ©Aidesign,2016<BR></font> <font size=5 color='forestgreen'>番号をタッチ、再実行は↻ボタンをタッチ。<BR></font> <canvas id="tutorial" width="688" height="528" style="border: 0px blue solid"></canvas> </body> </html>
実行例
16画像描画 Tiny-F.html, Ver 0.01, ©Aidesign,2016
番号をタッチ、再実行は↻ボタンをタッチ。