画像のドラッグ&ドロップによるRippleEffect特殊効果

2011年5月18日(水)
PROJECT KySS

Storyboardの作成

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

3

図21:RippleStoryboardという名前のストーリーボードを作成する(クリックで拡大)

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

「タイムラインとオブジェクト(B)」内のRippleEffectを選択し、タイムラインの黄色い再生ヘッドを0秒に合わせます。RippleEffectのプロパティ「Frequency」に40と指定します。「Magnitude」には0、Phaseには0と指定します。既に0が初期値として入力されている場合も、上書きで0と入力してください。Centerの値はデフォルトの0.5のままです。

「オブジェクトとタイムライン(B)」内のRippleEffectのEffect内に、いま設定したプロパティが追加されます(図22)。

3

図22:各プロパティが追加された(クリックで拡大)

次に、RippleEffectを選択した状態で、再生ヘッドを0.1秒の位置に移動し、「Frequency」に30、「Magnitude」に0.02、「Phase」に0と指定します。

次に、RippleEffectを選択した状態で、再生ヘッドを1.3秒の位置に移動し、「Frequency」に0、「Magnitude」に0、「Phase」に0と指定します。既に、0が入力されていても上書きで再入力してください。

0と上書き入力したプロパティにも、楕円のマークが追加されます(図23)。

3

図23:何も指定しなかったプロパティにも楕円のマークが追加されている

ここまでの手順をまとめると、表1のようになります。

表1 RippleStoryboard

プロパティ名 再生ヘッドの位置(秒)
0 0.1 1.3
Frequency 40 30 0
Magnitude 0 0.02 0
Phase 0 0 0

「●RippleStoryboardタイムライン記録オン」の●をクリックしてオフとし、Blend4を終了してVS2010に戻ります。

ソリューションエクスプローラー内のMainPage.xamlを展開して表示されるMainPage.xaml.vbをダブルクリックしてリスト3のコードを記述します。

ロジックコードを記述する

リスト3 (MainPage.xaml.vb)

Option Strict On
Partial Public Class MainPage
  Inherits UserControl

	Public Sub New()
  	InitializeComponent()
  End Sub

マウスの左ボタンが押されたか、離されたかを判別するブール型メンバ変数、myMouseCaptureを宣言します。
  Dim myMouseCaputer As Boolean
マウスポインタのY座標を格納するメンバ変数myYPosを宣言します。
  Dim myYPos As Double
マウスポインタのX座標を格納するメンバ変数myXPosを宣言します。
  Dim myXPos As Double
ImageがDropされた時のY座標を格納するメンバ変数myYDropPos変数を宣言します。
  Dim myYDropPos As Double

■ページが読み込まれた時の処理
  Image1のMouseLeftButtonUpイベント時に、Image1Droppedプロシージャを実行します。
  Image1のMouseLeftButtonDownイベント時に、Image1Largedプロシージャを実行します。
  	Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
  		AddHandler Image1.MouseLeftButtonUp, AddressOf Image1Dropped
  		AddHandler Image1.MouseLeftButtonDown, AddressOf Image1Larged
  	End Sub

■Image1上でマウスの左ボタンが押された時の処理
  カーソルを手の形にします。senderオブジェクトの持っているImageの情報を、DirectCastでImage型に変換し、変数myImageで参照します。マウスポインタの左上隅にあるY座標の値をメンバ変数myYPosに格納します。マウスポインタの左上隅にあるX座標の値をメンバ変数myXPosに格納します。Image1上でマウスの左ボタンが押されたため、ブール型の変数myMouseCaptureにTrueを指定しておきます。CaptureMouseメソッドで、Image1のマウスキャプチャを有効にします。
Private Sub Image1_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Image1.MouseLeftButtonDown
  	Image1.Cursor = Cursors.Hand
  	Dim myImage As Image = DirectCast(sender, Image)
  	myYPos = e.GetPosition(Nothing).Y
  	myXPos = e.GetPosition(Nothing).X
  	myMouseCaputer = True
  	myImage.CaptureMouse()
	End Sub

■Image1上でマウスの左ボタンが離された時の処理
  カーソルを矢印の形にします。senderオブジェクトの持っているImageの情報を、DirectCastでImage型に変換し、変数myImageで参照します。Image1上でマウスの左ボタンが離されたため、ブール型の変数myMouseCaptureにFalseを指定しておきます。ReleaseMouseCaptureメソッドで、Image1のマウスキャプチャを無効にします。Image1がDropされた時のY座標を格納するメンバ変数myYDropPos変数に、現在のマウスポインタのY座標の値を指定します。
  Private Sub Image1_MouseLeftButtonUp(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Image1.MouseLeftButtonUp
  	Image1.Cursor = Cursors.Arrow
  	Dim myImage As Image = DirectCast(sender, Image)
  	myMouseCaputer = False
  	myImage.ReleaseMouseCapture()
  	myYDropPos = myYPos
  End Sub

■Image1をマウスでドラッグして移動した時の処理
senderオブジェクトの持っているImageの情報を、DirectCastでImage型に変換し、変数myImageで参照します。Image1上でマウスの左が押されている場合に、以下の処理を実行します。
移動したマウスポインタのY座標の値から、マウスの左ボタンが押された時点で取得されたY座標の値(myYPos)を減算した値を、変数myVerticalに格納します。
移動したマウスポインタのX座標の値から、マウスの左ボタンが押された時点で取得されたX座標の値(myXPos)を減算した値を、変数myHorizontalに格納します。
myVerticalの値に、GetValueメソッドで取得したImage1の、CanvasのTopの値を加算した値を、変数myNewTopに格納します。
myHorizontalの値に、GetValueメソッドで取得したImage1の、CanvasのLeftの値を加算した値を、変数myNewLeftに格納します。
SetValueメソッドで、Image1のTopとLeftの値に、myNewTopとmyNewLeftの値を指定します。
現在のマウスポインタのY座標の値を、myYPosメンバ変数に格納しておきます。同様に、現在のマウスポインタのX座標の値を、myXPosメンバ変数に格納しておきます。
  Private Sub Image1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Image1.MouseMove
  	Dim myImage As Image = DirectCast(sender, Image)
  	If myMouseCaputer = True Then
  		Dim myVertical As Double = e.GetPosition(Nothing).Y - myYPos
  		Dim myHorizontal As Double = e.GetPosition(Nothing).X - myXPos
  		Dim myNewTop As Double = myVertical + DirectCast(myImage.GetValue(Canvas.TopProperty), Double)
  		Dim myNewLeft As Double = myHorizontal + DirectCast(myImage.GetValue(Canvas.LeftProperty), Double)
  		myImage.SetValue(Canvas.TopProperty, myNewTop)
  		myImage.SetValue(Canvas.LeftProperty, myNewLeft)
  		myYPos = e.GetPosition(Nothing).Y
  	myXPos = e.GetPosition(Nothing).X
  End If
End Sub

■Image1上でマウスの左ボタンが離された時の処理
マウスが離された時のマウスポインタのY座標の値が300より大きかった場合、つまり、Targetキャンバス内にImageがドロップされた時の処理です。
VisualStateManager.GotoStateメソッドで、画像が縮小するImageSmallの VisualSateを実行します。VisualStateManager.GotoStateメソッドの書式は下記の通りです。
VisualStateManager.GotoState(状態を遷移させるコントロール,状態名,VisualTransitionを使うかどうかのBoolean値(使用する場合はTrue、それ以外はFalse)
Targetキャンバス内にある現在のマウスポインタの位置をmyCP変数に格納し、XとY座標の位置を取得します。XとY座標の値を取得したmyCP変数の値を、RippleEffectのCenterプロパティの値に指定します。RippleEffectのストーリーボードを開始します。
マウスが離された時のマウスポインタのY座標の値が300以外の場合は、画像が元の状態に戻る(拡大する)、ImageLargeのVisualStateを実行します。
  Private Sub Image1Dropped(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
  	If myYDropPos > 300 Then
  		VisualStateManager.GoToState(Me, "ImageSmall", True)
  		Dim myCP As Point = e.GetPosition(Target)
  		myCP.X = myCP.X / Target.ActualWidth
  		myCP.Y = myCP.Y / Target.ActualHeight
  		myRippleEffect.Center = myCP
  		RippleStoryboard.Begin()
  	Else
  		VisualStateManager.GoToState(Me, "ImageLarge", True)
  	End If
  End Sub

■Image1のMouseLeftButtonDownイベント時に実行される処理
  マウスが押下された時のマウスポインタのY座標の値が、300より小さい場合は(マウスポインタがSourceという名前のCanvas内にあった時(図3参照))、処理を中止します。マウスポインタがSourceという名前のCanvas内にあった時には、画像をドラッグ&ドロップしても画像は何も変化しません。それ以外は、画像が拡大するImageLargeのVisualStateを実行します。
  Private Sub Image1Larged(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
  	If myYDropPos < 300 Then
  		Exit Sub
  	Else
  		VisualStateManager.GoToState(Me, "ImageLarge", True)
  	End If
  End Sub
End Class
  • 「画像のドラッグ&ドロップによるRippleEffect特殊効果」サンプルプログラム

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています