« 球の移動 -1- | トップページ | 球の移動 -3- »

2012年2月24日 (金)

球の移動 -2-

FlatTable の球の移動はドラッグによって行います。Flash だと、ドラッグの関数(メソッド)が用意されているので何の苦労も無く球をドラッグすることが出来ました。しかし、SVG+JavaScript では自前で処理しなければなりません。

ドラッグは次の手順で行います。

  1. ドラッグ開始を検知し、その時のマウスの座標を読み取る。
  2. マウスが動くたびにその座標を読み取り、1つ前の座標との差分を計算し、それを球の座標に加えて新たな座標を求めて、そこへ球を移動する。
  3. ドラッグ終了を検知し、ドラッグを終了する。

この手順でコーディングしたのですが、ここで問題発生です。マウスの座標はウィンドウ固有(ビューポート)の座標系を用いて表されています。そのスケールもウィンドウ固有のものです。しかし、FlatTable はウィンドウ・サイズに合わせて、適宜、拡大・縮小して使います。そのため、スケールは一律ではありません。すなわち、マウスと FlatTable は座標スケールが異る上に、その違いを前もって決定しておくことも出来ないのです。

何か解決策は無いかとインターネットで検索したり、掲示板で質問したりしたのですが、なかなか答えが見つからず何週間か経ち、やっと CTM(現在の変換行列)という解に辿り着きました。

SVG は画像を表示する時、画像の座標系からビューポートの座標系への変換を行っています。その変換行列が CTM で、CTM の成分 a が(少なくとも初期値は)変換の倍率になっています。CTM を読み取るメソッドは getCTM() です。

これらから、上記手順の2番目に関するコードは次のようになります。

var mag = 1/flattable.getCTM().a; function dragging(evt){ var dX = (evt.clientX - prevX)*mag; // スケール補正 var dY = (evt.clientY - prevY)*mag;  // ball.x += dX; ball.y += dY; ball.setAttribute("transform", "translate(" + ball.x + "," + ball.y + ")" );
prevX = evt.clientX; prevY = evt.clientY; return false; }

コード中、prevX, prevY は1つ前の座標です。evt はマウス移動のイベントです。

「スケール補正」の行では、マウスの移動距離を 、CTM の倍率を用いて補正してFlatTable 画像のスケールに合わせています。これで、マウスと球の移動量が一致することになります。

« 球の移動 -1- | トップページ | 球の移動 -3- »

ビリヤードの配置図ソフト」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/584699/54059869

この記事へのトラックバック一覧です: 球の移動 -2-:

« 球の移動 -1- | トップページ | 球の移動 -3- »