目標は商店街をつくる事なんです。

あきらめてるわけじゃないんです。今やっていることが、必ず力になると思うんです。

faceの作り方③ [face.js] shotEye();

こんにちは。いたかなやです。

今日も来て頂いてありがとうございます。





前回まで、

◎ひまつぶしアプリ face

◎ faceの作り方① ( index.html )

◎ faceの作り方② (face.js) canvas/context




f:id:itakanaya9:20131014191858p:plain



今回は、第4回、
faceの作り方③ [face.js] shotEye();
です。

ここでは、『目の飛び出す処理』を紹介したいと思います。

function shotEye(mx,my,exr,eyr,exl,eyl){//目が飛び出す処理
	var t;
	count = 1000;
	var callback = function(){
		count--;
		if (count > 0){
			clearCanvas();//canvasクリア
			place(mx,my);//座標の位置表示
			face();//顔の輪郭表示
			label();//faceのラベル表示
			var c = 1000-count
			eyes(exr+c*(exr-180),eyr+c*(eyr-180),10);
			eyes(exl+c*(exl-220),eyl+c*(eyl-180),10);
			t = setTimeout(callback, 0);
		}
	}
	t = setTimeout(callback, 0);
}


こんな感じのコードになっています。



function shotEye(mx,my,exr,eyr,exl,eyl)
と沢山の引数をうけているわけですが、

コレの説明から、

mx : canvas上のマウスのx座標

my : canvas上のマウスのy座標

マウスの座標は、左上が原点と考え、
右に行くほど、x座標は増加していき、
下に行くほど、y座標が増加していきます。


次に、

exr : 右目の位置を表すx座標

eyr : 右目の位置を表すy座標

exl : 左目の位置を表すx座標

eyl : 左目の位置を表すy座標


マウスの座標に対応して、目の位置を決めています。
これらは、次回紹介する。『マウスの処理』で計算され、
引数として、渡されていると理解しておいて下さい。





基本的には、

目の位置を計算
→ 描画
→ canvasをクリア
→ 目の位置を再計算
→ 再描画
→ ・・・

という流れになっています。






普通に考えれば、for文やwhile文などのループを使い、
上の流れを記述すれば、良いようなのですが、

while(count>0){//うまく描画できない例
      clearCanvas();//canvasクリア
      place(mx,my);//座標の位置表示
      face();//顔の輪郭表示
      label();//faceのラベル表示
      var c = 1000-count
      eyes(exr+c*(exr-180),eyr+c*(eyr-180),10);
      eyes(exl+c*(exl-220),eyl+c*(eyl-180),10);	
      count--;
}

これでは、うまく描画されないんです。





前に、objective-c を使っているときにも、
同じような事があったのを思い出し、
少し調べてみると、


関数の実行中は、描画を行わない。

そうです。




なので、関数の中でループを行い、そのループの中で、
canvasクリア → 再描画
と記述したところで、




実際に描画されるのは、
関数を終了した時なので、
最後の結果しか表示されません。





これでは、面白くないので、
上のように、
setTimeout()を使う。
というコードになっています。




以下setTimeout()の説明です。



setTimeout( 実行する関数 , タイムアウト時間 )
→タイムアウトした時点で、指定した関数を実行する事ができます。





この setTimeout() を使用し、
関数内で、自らの関数を呼び出す(コールバック?)ことによって、
自らが終了したときに描画が行われる

という仕組みです。



ループの停止は、
グローバル変数: count
を使用しています。
初期値は、1000に設定しています。
count--; で1回の描画ごとにcountの値を1ずつ減らしていき、
countの値が0になると終了するようにしています。






最後に、目の位置の計算式についてです。

var c = 1000-count
eyes(exr+c*(exr-180),eyr+c*(eyr-180),10);
eyes(exl+c*(exl-220),eyl+c*(eyl-180),10);


前回紹介させていただいた。eyes()関数を使用しています。

右目の中心の座標は、(180,180)
左目の中心の座標は、(220,180)

に設定しています。


中心から、
描画するごとにマウスの位置に向かって、
目の座標を変化させています。


目の近くで、クリックするのと、
目の遠くで、クリックするのでは、

目が飛び出す速度に違いがあったと思います。


これは、exr,exl,eyr,eyl の値の大きさによって、

目の位置の変化の値が変わってくるからです。







長くなりましたが、今日は以上です。


setTimeout()に関しては、これからも色々使いそうなので、
覚えておきたいと思います。




次回は、マウスの座標を取得するなどの処理を
まとめていきたいと思います。



お付き合い、ありがとうございました。