連載
» 2013年12月16日 18時00分 公開

2カ月で160本作った還暦開発者が送る10のアプリ開発ノウハウ(10):ストーリーボードを使い画像をY軸を中心に立体的に回転させるには (3/3)

[薬師寺国安,PROJECT KySS]
前のページへ 1|2|3       

選択したフォルダー内の画像を表示して、マウスの移動で、画像を、Y軸を中心に回転させたり、ImageShowStoryboardを実行する処理

 今回のアプリの肝となる処理だ。ストーリーボード処理をプログラムから行っている。

Private Async Function DataShow() As Task
        For Each result In myImageCollections
            myBmp = New BitmapImage
            myBmp.SetSource(Await result.OpenReadAsync)
            myImage = New Image
            With myImage
                .Width = 160
                .Height = 120
                .Source = myBmp
                .Stretch = Stretch.Uniform
            End With
            Dim fileNameTextBlock As New TextBlock
            With fileNameTextBlock
                .Width = 160
                .FontSize = 18
                .TextAlignment = TextAlignment.Center
                .TextWrapping = TextWrapping.Wrap
                .Text = result.Name
            End With
            Dim myStackPanel As New StackPanel
            myStackPanel.Margin = New Thickness(3)
            myStackPanel.Children.Add(myImage)
            myStackPanel.Children.Add(fileNameTextBlock)
            GridView1.Items.Add(myStackPanel)
            AddHandler myImage.PointerEntered, Sub(mySender As Object, myArgs As PointerRoutedEventArgs)
                    Dim _myImage = DirectCast(mySender, Image)
              ‘これより以下が、このアプリの肝。ストーリーボード処理をプログラム上で行う。
                    Dim myStoryBoard As New Storyboard
                    myStoryBoard.Stop()
                    Dim myPlaneProjection As PlaneProjection = DirectCast(_myImage.Projection, PlaneProjection)
                    If _myImage.Projection Is Nothing = True Then
                          myPlaneProjection = New PlaneProjection
                         _myImage.Projection = myPlaneProjection
                    End If
                   Dim myDoubleAnimation As New DoubleAnimation
                   With myDoubleAnimation
                      .From = 0
                      .To = 360
                      .Duration = New Duration(TimeSpan.FromSeconds(3))
                   End With
                   Storyboard.SetTarget(myDoubleAnimation, myPlaneProjection)
                Storyboard.SetTargetProperty(myDoubleAnimation, "myPlaneProjection.RotationY")
                   myStoryBoard.Children.Add(myDoubleAnimation)
                   myStoryBoard.Begin()
                        AddHandler _myImage.DoubleTapped, Sub()
                            Image1.Visibility = Windows.UI.Xaml.Visibility.Visible
                            Image1.Source = _myImage.Source
                           _StoryBoard = New Storyboard
                           _StoryBoard = DirectCast(Me.Resources("ImageShowStoryboard"), Storyboard)
                           _StoryBoard.Begin()
                                End Sub
                  End Sub
        Next
        ProgressRing1.IsActive = False
        ProgressRing1.IsEnabled = False
    End Function

 以降、上記コードの中身を詳細に見ていこう。

 まず、非同期処理で行われるためメソッドの先頭にAsyncを追加している。

 次に、指定したフォルダー内の画像を保持している、メンバーコレクション変数myImageCollections内のファイルを、変数resultに格納しながら、以下の処理を行う。

 新しいBitmapImageのインスタンスmyBmpオブジェクトを作成する。SetSourceメソッドに、「Await result.OpenReadAsync」と指定して、各画像に対して、ランダムアクセス用のストリームを開く。SetSourceメソッドは、ストリームにアクセスしてBitmapSourceのソースイメージを設定するメソッドだ。

 Imageクラスの新しいインスタンスmyImageオブジェクトを作成する。Widthに「160」、Heightに「120」と指定し、SourceプロパティにmyBmpオブジェクトを指定する。Stretchプロパティには「Uniform」を指定しておく。

 TextBlockの新しいインスタンスfileNameTextBlockオブジェクトを作成する。Widthに「180」、文字サイズに18、文字位置は中央揃え、文字の折り返しは可能と指定する。[Text]プロパティには、Nameでファイル名拡張子を含む項目の名前を取得して、指定する。

 新しいStackPanelのインスタンスmyStackPanelオブジェクトを作成する。Marginプロパティに「3」を指定して余白を設ける。AddメソッドでmyImageとfileNameTextBlocオブジェクトを追加する。最後にGridView1にAddメソッドでmyStackPanelオブジェクトを追加する。これで、画像の下にファイル名が表示されて、GridView1に画像の一覧が表示される。

 AddHandlerステートメントで、myImageオブジェクトのヒットテスト領域にポインターが入ったときに発生する、PointerEnteredイベントにイベントハンドラーを追加する。イベントハンドラー内では以下の処理を行う。

 オブジェクト変数mySenderに格納されているImageオブジェクトを取得し、_myImageで参照しておく。

 新しいStoryboardのインスタンスmyStoryBoardオブジェクトを作成する。

 _myImageオブジェクトのPlaneProjectionを取得し、変数myPlaneprojectionで参照しておく。PlaneProjectionはオブジェクトに対する遠近法変換を表すクラスだ。

 このサンプルでは、プログラムコードで_myImage(Image)オブジェクトを作成しているため、_myImageオブジェクトにProjectionプロパティが設定されていない場合の処理が必要になる。

 新しいDoubleAnimationのインスタンスmyDoubleAnimationオブジェクトを作成する。Y軸に沿ってオブジェクトを一回転させるため、Fromに「0」を指定し、Toに「360」、Durationに「3秒」を指定する。3秒かかって画像がY軸を中心に360度回転することになる。

 SetTargetメソッドでタイムラインにDoubleAnimationのインスタンスであるmyDoubleAnimationオブジェクトを指定し、タイムラインの対象となるオブジェクトに、PlaneProjectionのインスタンスであるmyPlaneProjectionを指定する。

 SetTargetPropertyメソッドで、タイムラインにDoubleAnimationのインスタンスmyDoubleAnimationオブジェクトを指定し、パスに"myPlaneProjection.RotationY"と指定する。

 StoryboardのインスタンスmyStoryBoardオブジェクトにAddメソッドでmyDoubleAnimationオブジェクトを追加する。Beginメソッドでアニメーションを開始する。

 AddHandlerステートメントで、_myImageオブジェクトがダブルタップされたときのイベントDoubleTappedに、イベントハンドラーを追加する。イベントハンドラー内では以下の処理を行う。

 Image1を表示し、SourceプロパティにImageオブジェクトの「_myImage.Source」の値を指定する。

 新しいStoryboardのインスタンス_StoryBoardオブジェトを作成する。XAML内の内に記述している、ImageShowStoryboardを取得し、Beiginメソッドでアニメーションを開始する。ProgressRing1の動作を停止する。

 以上のコードで、画像一覧の上にマウスカーソルを乗せると、画像がY軸を中心に回転し、任意の画像をダブルタップすると画像が回転しながら表示され、小さくなって消えていく。

ImageShowStoryboardのアニメーションが完了したときの処理(_StoryBoard_Completedメソッド処理)

    Private Sub _StoryBoard_Completed()
        Image1.Visibility = Windows.UI.Xaml.Visibility.Collapsed
        _StoryBoard.Stop()
    End Sub

 ここでは、Image1を非表示にし、アニメーションを停止している。

終わりに

 今回で10回にわたった、Windowsストアアプリ開発の解説は終了です。長い間のお付き合いを感謝いたします。1つの完成されたアプリの中で、アプリの作成方法をメインに解説してきましたが、いかがだったでしょうか?

 この連載が、皆さまのWindowsストアアプリ開発の助けになれば、筆者としてはうれしい限りです。どうもありがとうございました。また、お会いできる日まで……。

著者プロフィール

PROJECT KySS 薬師寺 国安(やくしじ くにやす)

1950年生まれ。フリーVBプログラマ。高級婦人服メーカーの事務職に在職中、趣味でVBやActiveXに取り組み、記事を執筆。2003年よりフリー。.NETやRIAに関する執筆多数。Windowsストアアプリも多数公開中(約270本)。

 

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。

Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。

Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。

PROJECT KySSは、1997年に薬師寺聖と結成したコラボレーション・ユニット


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。