faceの作り方③ [face.js] shotEye();
こんにちは。いたかなやです。
今日も来て頂いてありがとうございます。
前回まで、
◎ faceの作り方② (face.js) canvas/context
今回は、第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()に関しては、これからも色々使いそうなので、
覚えておきたいと思います。
次回は、マウスの座標を取得するなどの処理を
まとめていきたいと思います。
お付き合い、ありがとうございました。