Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
Leap Motion実用サンプル(Visual Basic編)

Leap Motion実用サンプル(Visual Basic編)

画像をタップした位置にRippleEffectで波紋を起こす

2013年11月25日

トランジションを使って、空中タッチした画像の位置に波紋を発生させるサンプルWPFアプリを作ってみよう。

  • このエントリーをはてなブックマークに追加

 今回は、「RippleEffect」という波紋を起こさせるトランジション(Transition)を使って、空中タッチした画像の位置に波紋を発生させるWPFアプリを作成する。さっそく、その開発内容を説明していこう。

まずWPFプロジェクトを作成しよう

 今回のLeap MotionアプリもWPFで作成する。これまでの連載の手順と同様に、Visual Studio 2012(以下、VS 2012)のIDEを起動してVisual Basicの「WPFアプリケーション」テンプレートで新規プロジェクトを作成する。[名前]欄には、ここでは「RippleEffectLeapMotion」と指定する。

 ソリューションエクスプローラーでプロジェクト内にImageフォルダーを作成して、1枚の画像を配置しておく。読者は自分の好きな画像を配置するといい。できれば画像サイズは640×480pxが望ましい。画像の種類はPNGでもJPEGでもOKだ。

 WPFの基本的な作成手順は、第1回と同じ手順となるので、説明を割愛する。具体的な手順は、第1回の「参照の追加」「プロジェクトのルートに「LeapCSharp.dll」と「Leapd.dll」を追加する」「プロパティを設定する」を参考にしてほしい。

今回のLeap Motionアプリについて

 今回のアプリは、表示させた画像の上で、タッチ動作を行うと、画像の上に波紋が発生するアプリだ(次の画面を参照)。

画像上をタッチして波紋を起こさせている

 この波紋にはRippleEffect効果を使用している。

画面のレイアウト(MainWindow.xaml)

 VS 2012のデザイン画面上に、「image」という名前のImageコントロールを1個配置する。そのWidthプロパティには「640」、Heightプロパティには「480」を指定し、SourceプロパティにImageフォルダーに取り込んでおいた画像を指定する。

 一番前面に(つまり最後の行に)、「paintCanvas」という名前のInkPresenterを配置する。これはタッチ・ポイントを表示するためのものだ。

 書き出されるXAMLコードは次のリストのようになる。

XAML
<Window x:Class="MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="MainWindow" Height="1080" Width="1920" WindowState="Maximized">
  <Grid>
    <Image x:Name="image" HorizontalAlignment="Left" Height="480" Margin="265,80,0,0" VerticalAlignment="Top" Width="640" Source="Image/林_03.png"/>
    <InkPresenter Name="paintCanvas"/>
  </Grid>
</Window>
リスト1 書き出されたMainWindow.xamlファイルのコード内容

Blendを起動してストーリーボードを作成

 次に、アニメーションのためのストーリーボードを作成する。

 まずはBlendを起動する(起動手順は、第3回を参考にされたい)。なお、実際にBlendを起動する前に、必ずVS 2012でプロジェクトをビルドしておこう。

 Blendが起動したら、[プロジェクトを開く]から、現在作成している「RippleEffectLeapMotion.sln」ファイルを指定して開く。

 Blendの[アセット]パネルをクリックし、[コントロール]から「Ripple」を検索して表示させる。「検索」欄に「Ripp」と入力すると、Rippleが表示される(次の画面を参照)。

[検索]欄に「Ripp」と入力することで、「Ripple」が表示された
[検索]欄に「Ripp」と入力することで、「Ripple」が表示された

 表示されたRippleを「オブジェクトとタイムライン」内のimage要素上にドラッグ&ドロップする(次の画面を参照)。

Rippleをimage上にドラッグ&ドロップした
Rippleをimage上にドラッグ&ドロップした

 追加したRippleEffectを選択して表示されるプロパティの、[名前]に「myRippleEffect」と指定し、[Frequency]に「0」、 [Magnitude]に「0」、 [Phase]に「0」と指定しておく(次の画面を参照)。Frequencyにはシェーダー内の周波数の値を指定する。Magnitudeにはシェーダー内の振幅の値を指定する。Phaseにはシェーダー内のフェーズ値を指定する。

RippleEffectのプロパティを設定する
RippleEffectのプロパティを設定する

ストーリーボードの作成

 「RippleEffectStoryboard」というストーリーボードを作成する(作成手順は「MSDN: ストーリーボードの作成、変更、または削除」を参照されたい)。

 [オブジェクトとタイムライン]の下にあるストーリーボードの[新規作成]アイコン(+)をクリックし、「RippleEffectStoryboard」というストーリーボードを作成する。

 アートボード上の画面全体が赤の枠線で囲まれ、「●RippleEffectStoryboardタイムライン記録オン」に変わる。この状態でタイムラインの記録が可能になる。

 これから以下の作業は、再生ヘッドの位置に応じて、各プロパティの値を設定する作業となる。これらのプロパティ値は、表1にまとめているので、そちらを参考に値を設定してほしい。

プロパティ名再生ヘッドの位置(秒EasingFunction
 00.30.6 
Frequency 30 記録なし 0 CubicInOut
Magnitude 0 0.20 0 CubicInOut
Phase 0 記録なし 0 CubicInOut
RippleEffectStoryboardの再生ヘッドの位置とその値

 [Frequency]、[Magnitude]、[Phase]を選択して表示されるプロパティの[EasingFunction]に、「CubicInOut」を選択する(次の画像を参照)。[Frequency]、[Magnitude]、[Phase]全てに対して設定する。

[EasingFunctionに、CubicInOutを指定する
[EasingFunctionに、CubicInOutを指定する

 Blendを終わらせて、VS 2012に戻る。保存と適用のメッセージが出るが、保存して適用させる。

 またストーリーボードのコードの下に、次のリストのコードが追加されているので、このコードは削除する。このコードを残したままにしておくと、アプリを実行した際に、即!ストーリーボードが実行されてしまう。

XAML
<Window.Triggers>
  <EventTrigger RoutedEvent="FrameworkElement.Loaded">
    <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
  </EventTrigger>
</Window.Triggers>
リスト2 削除するコード

 MainWindow.xamlファイル内に<Image>要素が次のリストのように書き出されている。ここでさらに。<ee:RippleEffect>要素のx:Name属性に「myRiffleEffect」を指定して、名前を付けておく。

XAML
<Image x:Name="image" HorizontalAlignment="Left" Height="480" Margin="265,80,0,0" VerticalAlignment="Top" Width="640" Source="Image/林_03.png">
  <Image.Effect>
    <ee:RippleEffect Frequency="0" Magnitude="0" Phase="0" x:Name="myRiffleEffect"/>
  </Image.Effect>
</Image>
リスト3 書き換えられたImageコントロール

プログラムコード(MainWindow.xaml.vb)

 では、次にプログラムコード(MainWindows.xaml.vbファイル)を見ていこう。

 プログラムコードも、タッチ処理以外は第1回と基本的に同じ内容となるので、説明を割愛する。まずは第1回の「名前空間の読み込み」「メンバー変数の宣言」「MainWindow_Loadedメソッドの処理」「Updateメソッドの処理」の開発手順を参考にタッチ処理の前までを実装してほしい。相違点として、下記の3点を修正してほしい。

 (1)ストーリーボードを扱うため、System.Windows.Media.Animation名前空間を読み込む。

 (2)Storyboardクラス型のメンバー変数「Public stb As Storyboard」を宣言する。

 (3)「Private x As Integer」、「Private y As Integer」、「Private tx As Double」、「Private ty As Double」、「Private FingersCount As Integer」、「Private Message As String」、「Private Index As Integer」の行は、今回は不要なので削除する。

MainWindow_Loadedメソッドの処理

 ~第1回目と同じ処理の解説になるので割愛する。~

Updateメソッドの処理

 ~第1回目と同じ処理の解説になるので割愛する。~

Updateメソッドの処理(タッチ処理部分)

 次にLeap Motionのタッチ処理になる。

 タッチのイメージについては、第5回の「Updateメソッドの処理(タッチ処理部分)」を参考にしてほしい。

 まずホバーの場合は、表示されている円がBlueの色になるだけで、何も起きない。具体的には下記のコードのようになる。

Visual Basic
For Each Pointable As Pointable In leap.Frame.Pointables
  ……コード略(前述)……

  If Pointable.TouchDistance > 0 AndAlso Pointable.TouchZone <> Global.Leap.Pointable.Zone.ZONENONE Then
    touchIndicator.Color = Colors.Blue
    ……コード略(続きは後述)……

  End If

Next
リスト4 ホバー時の処理(MainWindow.xaml)

 次にタッチした処理になる。タッチした場合は、表示されている円がRedに変わる。

 円の色が赤から青に変化した瞬間(=空中タッチした指を手前に引っ込めた瞬間)にRippleEffect効果が発生する。空中タッチした円の色が赤の状態では、まだRippleEffect効果は表れないので、注意してほしい。青に変わった時点で発生する。

 ポインターのX座標の値をimageコントロールのWidthプロパティの値である「640」で除算し、現在のポインターのX座標の値とする。取得したポインターのY座標の値をimageコントロールのHeightプロパティの値である「480」で除算し、現在のポインターのY座標の値とする。これらのX/Y座標をmyRippleEffectオブジェクトのCenterプロパティの値に指定する。「Me.Resources("RippleEffectStoryboard")」というコードで、Windows.Resource内のストーリーボードを取得して、変数「stb」に格納する。その変数のBeginメソッドでストーリーボードを開始する。タッチした点の周囲に波紋が広がる。

 具体的には以下のコードになる。

Visual Basic
If Pointable.TouchDistance > 0 AndAlso Pointable.TouchZone <> Global.Leap.Pointable.Zone.ZONENONE Then
  touchIndicator.Color = Colors.Blue
  ……コード略(続きは後述)……

ElseIf Pointable.TouchDistance <= 0 Then

  touchIndicator.Color = Colors.Red

  touchPoint.X = touchPoint.X / 640
  touchPoint.Y = touchPoint.Y / 480

  ' 現在のポインターのX/Y座標の値をCenterプロパティに設定する
  myRiffleEffect.Center = touchPoint

  ' RippleEffectStoryboardを取得し、Beginメソッドで開始する
  stb = TryCast(Me.Resources("RippleEffectStoryboard"), Storyboard)
  stb.Begin()

  'タッチ対象外
Else
  touchIndicator.Color = Colors.Gold
End If
リスト5 タッチした周囲に波紋が広がる(MainWindow.xaml)

 このサンプルのコードは下記よりダウンロードできる*1

  • *1サンプルをダウンロードして動かす場合は、「LeapCSharp.NET4.0.dll」や「LeapCSharp.dll」、「Leap.dll」を読者自身のフォルダー内にあるDLLファイルに指定し直さなければ動かない可能性があるので、動かない場合は再指定していただきたい。

 RippleEffectの波紋が、タッチしたポイントを中心に発生しない点が、ちょっと気に入らないが、WPFのストーリーボードと絡めるとこのようなこともできるのは示せただろう。コードはダウンロードできるので、タッチした点を中心に波紋が発生するよう、読者の皆さんにも挑戦していただきたい。

 さて、Leap Motionのサンプルは、今回で最終回だ。いかがだっただろうか? Leap Motionには、もっともっと無限の可能性が秘められていると思う。その無限の可能性は、皆さんのアイデアの中にある。この連載をきっかけに、ぜひLeap Motionのアプリ作成に挑戦していただきたい。

 またLeap Motionをお持ちでない方も、このサンプルを見て、自分も購入して、アプリ開発をやってみようかな……と思われたなら、この連載は成功だ。そうなれば筆者としてもうれしいのだが、いかがだっただろうか。

 またお会いできる日を楽しみしておこう。

※以下では、本稿の前後を合わせて5回分(第5回~第9回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

Leap Motion実用サンプル(Visual Basic編)
5. Leap MotionでBing Mapsを扱う

リスト内に表示された住所項目をLeap Motionによりタッチすることで、Web上のサービス「Bing Maps」での地図検索を行うサンプル・アプリを作ってみよう。

Leap Motion実用サンプル(Visual Basic編)
6. Leap MotionでWebカメラを操作する

Leap MotionでWebカメラを操作して、撮った写真画像にフレームを合成したり、音声を録音したりできるWPFアプリを作ってみよう。

Leap Motion実用サンプル(Visual Basic編)
7. 3D回転で表示される画像をLeap Motionで切り替える

画像が立体的に回転して表示され、Leap Motionで任意の画像を空中タッチすると、アニメーションを伴ってその画像が大きく表示されるサンプルWPFアプリを作ってみよう。

Leap Motion実用サンプル(Visual Basic編)
8. Leap Motionの軌跡に従って連続した円を描く

Leap Motionで取得した手の動きに合わせて、ランダムな色の円が大きくなりながら連続で描画されるサンプルWPFアプリを作ってみよう。

Leap Motion実用サンプル(Visual Basic編)
9. 【現在、表示中】≫ 画像をタップした位置にRippleEffectで波紋を起こす

トランジションを使って、空中タッチした画像の位置に波紋を発生させるサンプルWPFアプリを作ってみよう。

サイトからのお知らせ

Twitterでつぶやこう!