読者です 読者をやめる 読者になる 読者になる

連載執筆中

去年の暮れから Silverlight の連載を執筆中です。
始めよう!Silverlight
明後日あたりに第3回が掲載される予定です。


今回はサンプルをダウンロードできるようにしたのですが、このサンプルにちょっと凝ってみました。カードをドラッグドロップで移動できるようにしているのですが、ドロップしたときにマウスが動いている途中なら、滑って止まるってふうにしてみました。まぁ、最近ではありがちな感じのやつです。

しかしこれがなかなか苦労しました。きれいに滑らせようと思ったら次の条件が必要です。

  • 最後に取得したマウスの位置と、その直前のマウスの位置の差分が分かる。
  • 滑らせている最中は等間隔の時間で上記の差分を減らしていく。
  • 最後と、その直前のマウスの位置を取得する時間間隔は、上記の滑らせている時間間隔と同間隔である必要がある。

ってことで、マウスの位置はタイマーで取得しなければダメなんですね。通常だと MouseMove イベントを拾って、そこでドラッグ中のオブジェクトを移動させるのですが、それではダメなのです。ってことで、タイマーを使おうって話になるのですが、javascript の setInterval とかだとあれって完全にパラで動いているのではなくキューに貯めて割り込み処理してるので間隔が狂ってしまうのです。で、調べてみたら Storyboard に何の時間も設定せずに動かすとフレームレートをもとに Complete イベントが発生するみたいです。なので、ドラッグ中のオブエジェクトを移動させるコードとか滑らせるコードとかは、その Complete イベントで行うことにしました(でも、これが完全に等間隔でパラで発生するかどうかの検証はしてません)。最後に問題になるのは、マウスの位置。これは残念ながらいまのところマウスのイベントが発生した時の引数でしか取得できません。つまり、 Storyboard の Complete イベントでは取得できません。で、どうしようかと考えに考えたあげく、 MouseMove イベントで現在のマウス位置を取得して保持しておく方法をとりました。ちょいとベタベタな気もしますが。。良い方法をご存じであれば是非連絡ください。

実はこの処理、FlexActionScript だとめっちゃ簡単やったりします。なんせフレームのイベントを拾えたり、いまのマウスの位置をいつでも普通に取得できるのですから。

フレームのイベントを拾えるのはどっちでもいいとして、マウスの位置は自由なタイミングで取得できるようになってくれると非常に助かるのですが。どうでしょか? Microsoft さん。