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

まず初めに、このプログラムで実装する機能の動作を、下記に解説しておきます。

上段に少し大きめの画像が、下段には複数の小さめの画像が配置されています(図1)。上段の画像を下段の画像の集団にドラッグ&ドロップすると、画像のサイズが、RippleEffect効果を伴って、下段内の画像のサイズと同じになります(図2)。 RippleEffectは、画像に波紋をシミュレートする効果です。上段に画像をドラッグ&ドロップした場合は、画像サイズは元の大きいサイズのままになっています。

3

図1:上段に少し大きめの画像が配置され、下段には複数の小さめの画像が配置されている(クリックで拡大)

3

図2:上段の少し大きめの画像を、下段にドラッグ&ドロップすると、RippleEffect効果を伴って、画像サイズが同じになる(クリックで拡大)

今回のサンプルは以下よりダウンロードできます。
→ 今回のサンプルファイル(2.43MB)

新規プロジェクトの作成

早速サンプルを作っていきましょう。本稿では開発言語にVisual Basicを用います。

VS 2010のメニューから[ファイル(F)/新規作成(N)/プロジェクト(P)]を選択します。次に、「Silverlight アプリケーション」を選択して、「名前(N)」に任意のプロジェクト名を指定します。ここでは「SL4_ImageDropRipple」という名前を付けています。

ソリューションエクスプローラー内にImageというフォルダを作成して、4枚の画像も追加しておきます。ダウンロードされたサンプル・ファイルには画像は追加済みです。

コントロールの配置

<UserControl>要素のWidthに800、Heightに600と指定します。ツールボックスからCanvasコントロールを配置します。Widthが800、Heightが300のCanvasコントロールを2個、上下に配置します。先に下のCanvasを配置し、x:NameにTargetと指定します。次に、上にCanvasを配置し、x:NameにSourceと指定します(図3)。書き出されるコードはリスト1のようになります。

3

図3:Canvasを上下に2個配置する(クリックで拡大)
リスト1 書き出されたXAMLコード(MainPage.xaml)
01<UserControl x:Class="SL4_ImageDropRipple.MainPage"
06  mc:Ignorable="d"
07  d:DesignHeight="300" d:DesignWidth="400" Width="800" Height="600">
08  <Grid x:Name="LayoutRoot" Background="White">
09    <Canvas Height="300" HorizontalAlignment="Left" Margin="0,300,0,0" x:Name="Target" VerticalAlignment="Top" Width="800" />
10    <Canvas Height="300" HorizontalAlignment="Left" x:Name="Source" VerticalAlignment="Top" Width="800" />
11  </Grid>
12</UserControl>

次にSourceのCanvas内にImageコントロールを1個配置します。Widthに320、Heightに240を指定し、SourceプロパティにImageフォルダ内の画像を指定します。ここでは「菜の花.jpg」を指定しています。

同様にTargetのCanvas内に3個のImageコントロールを適当な位置に配置し、SourceプロパティにImageフォルダ内の画像を指定します。この場合のImageコントロールのWidthは160、Heightは120としておきます(図4)。

3

図4:2つのCanvas内にImageコントロールを配置し画像を読み込む(クリックで拡大)

書き出されるコードはリスト2のようになります。

リスト2 書き出されたXAMLコード(MainPage.xaml)
01(1)x:NameがTargetの<Canvas> 要素内に3個の<Image>要素を配置しています。Widthは160、Heightは120としています。
02(2)x:NameがSourceの<Canvas>要素内に1個の<Image>要素を配置しています。Widthは320、Heightは240としています。
03<UserControl x:Class="SL4_ImageDropRipple.MainPage"
08    mc:Ignorable="d"
09    d:DesignHeight="300" d:DesignWidth="400" Width="800" Height="600">
10 
11    <Grid x:Name="LayoutRoot" Background="White">
12    <Canvas Height="300" HorizontalAlignment="Left" Margin="0,300,0,0" x:Name="Target" VerticalAlignment="Top" Width="800"> ■(1)
13        <Image Canvas.Left="614" Canvas.Top="17" Height="120" Name="Image2" Stretch="Fill" Width="160" Source="/SL4_ImageDropRipple;component/Image/桜.jpg" />
14        <Image Canvas.Left="335" Canvas.Top="163" Height="120" Name="Image3" Stretch="Fill" Width="160" Source="/SL4_ImageDropRipple;component/Image/黄色い花.jpg" />
15        <Image Canvas.Left="31" Canvas.Top="17" Height="120" Name="Image4" Stretch="Fill" Width="160" Source="/SL4_ImageDropRipple;component/Image/ポピー.jpg" />
16    </Canvas>
17    <Canvas Height="300" HorizontalAlignment="Left" x:Name="Source" VerticalAlignment="Top" Width="800"> ■(2)
18        <Image Canvas.Left="230" Canvas.Top="27" Height="240" Name="Image1" Stretch="Fill" Width="320" Source="/SL4_ImageDropRipple;component/Image/菜の花.jpg" />
19    </Canvas>
20  </Grid>
21</UserControl>

ソリューションエクスプローラー内の、MainPage.xamlを選択し、マウスの右クリックで表示されるメニューの、「Expression Blendを開く(X)」を選択し、Blend4を起動します。

Blend4でのImageのDropShadowEffec(陰影)の設定

表示されている4枚の画像を全て選択し、プロパティの[外観]パネル内のEffectの横にある[新規作成]ボタンをクリックします。「オブジェクトの選択」画面が表示されますので、DropShadowEffectを選択します(図5)。

3

図5:DropShadowEffectを選択する(クリックで拡大)

全てのImageコントロールを選択していたのを解除し、一番大きい画像のImage1を選択します。プロパティの[外観]パネル内のEffectの左に、矢印アイコンが表示されますので、これをクリックするとDropShadowEffectの各種プロパティが設定できます。BlurRadiusには影のぼかし程度の値を指定します。ここでは12を指定します。Colorには影の色を指定します。ShadowDepthにはImageと影との距離の値として、20を指定します。そのほかはデフォルトのままです(図6)。ほかの3枚のImageにも同じ値を指定します。

3

図6:DropShadowEffectのプロパティを設定する

Blendの画面上では、DropShasowEffectが適用した形では表示されませんが、Blend4のメニューの「プロジェクト(P)/プロジェクトの実行(R)」で実行すると、DropShadowEffectが適用されているのがわかります(図7)。またVS2010画面上では、DropShadowEffectが適用されて表示されます。

3

図7:DropShadowEffectが適用されている(クリックで拡大)

Canvasの背景色の設定

次に、2つのCanvasの背景色を設定します。「オブジェクトとタイムライン(B)」から、Sourceを選択し、プロパティの[ブラシ]パネルにあるBackgroundを選択します。「グラデーションブラシ」アイコンをクリックします(図8)。

3

図8:Canvas(Source)の背景色に「グラデーションブラシ」を適用する

上から下に向かってグレー系統色のグラデーションがかかります。上の方が暗くなり、下に向かって明るくなっているのを逆にします。色の「エディター」内の2つのカラーストップを左右入れ替えることで、上下の明暗のグラデーションが逆になります(図9)。上の方が明るく下の方が暗いグラデーションになります。

3

図9:カラーストップを左右逆にする(クリックで拡大)

同じようにTargetのCanvasにも背景色にグラデーションを設定します。グラデーションの明暗の向きはそのままで構いません。全体に、中心が暗く外に向かって明るくなるグラデーションがかかります(図10)。

3

図10:2つのCanvasの背景色にグラデーションを指定した(クリックで拡大)

状態(S)の設定

「状態(S)」パネルの「状態グループの追加」アイコンをクリックし(図11)、さらに「状態の追加」アイコンをクリックします(図12)。

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

「ImageSmall」という名前を入力します(図13)。「タイムラインを表示する」アイコンをクリックして、タイムラインを表示します(図14)。

3

図11:「状態グループの追加」アイコンをクリックする

3

図12:「状態の追加」アイコンをクリックする

3

図13:「ImageSmall」という名前を入力する

3

図14:タイムラインを表示する

「オブジェクトとタイムライン(B)」からImage1を選択します。黄色の再生ヘッドが0の位置で、楕円マークと+の追加された、「キーフレームの記録」アイコンをクリックします。Image1の再生ヘッドが0の位置に楕円マークが表示されます(図15)。

3

図15:Image1の再生ヘッドが0の位置に楕円マークが表示された

次に再生ヘッドを0.5の位置に移動し、プロパティの[変換]パネルにある、RenderTransformの「拡大縮小」アイコンをクリックし、Xに0.5、Yに0.5と入力します。Image1の画像が縮小されます(図16)。

3

図16:RenderTransformの「拡大縮小」のXに0.5、Yに0.5と指定する(クリックで拡大)

「●ImageSmall状態記録オン」の●をクリックして、タイムラインの記録をオフにします。

同様な手順で、ImageLargeという状態を追加します。タイムラインの記録をオフの状態にして、Image1を選択し、再生ヘッドが0の位置で、プロパティの[変換]パネルにあるRenderTransformの「拡大縮小」のXとYの値に0.5と入力します。

「●ImageLarge記録オフ」の●をクリックして、記録オンにします。再生ヘッドが0の位置で、「キーフレームの記録」アイコンをクリックします。再生ヘッドを0.5の位置に移動し、RenderTransformの「拡大縮小」のXとYの値に1と入力します(図17)。ここまでの手順はImage1が選択された状態で行ってください。

3

図17:ImageLargeのタイムラインを記録する。Image1のRenderTransformの「拡大縮小」のXとYに1を入力し画像が元のサイズに戻ってる(クリックで拡大)

「●ImageLarge状態記録オン」の●をクリックして、記録オフにしてください。Image1が、元のサイズの状態である、再生ヘッドが0.5の位置で記録をオフにしてください。

Ripple特殊効果の設定

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

3

図18:「検索」欄に「Ripp」と入力して、Rippleが表示された

表示されたRippleを「オブジェクトとタイムライン(B)」内のTarget要素上にドラッグ&ドロップします(図19)。

3

図19:RippleをTarget上にドラッグ&ドロップした

Targetの子として追加された、RippleEffectを選択して表示されるプロパティの「名前」に、myRippleEffectと指定し、Frequencyに0、 Magnitudeに0、 Phaseに0と指定しておきます(図20)。Frequencyにはシェーダー内の周波数の値を指定します。Magnitudeにはシェーダー内の振幅の値を指定します。Phaseにはシェーダー内のフェーズ値を指定します。

3

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

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
プロパティ名再生ヘッドの位置(秒)
00.11.3
Frequency40300
Magnitude00.020
Phase000

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

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

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

リスト3 (MainPage.xaml.vb)
01Option Strict On
02Partial Public Class MainPage
03  Inherits UserControl
04 
05    Public Sub New()
06    InitializeComponent()
07  End Sub
08 
09マウスの左ボタンが押されたか、離されたかを判別するブール型メンバ変数、myMouseCaptureを宣言します。
10  Dim myMouseCaputer As Boolean
11マウスポインタのY座標を格納するメンバ変数myYPosを宣言します。
12  Dim myYPos As Double
13マウスポインタのX座標を格納するメンバ変数myXPosを宣言します。
14  Dim myXPos As Double
15ImageがDropされた時のY座標を格納するメンバ変数myYDropPos変数を宣言します。
16  Dim myYDropPos As Double
17 
18■ページが読み込まれた時の処理
19  Image1のMouseLeftButtonUpイベント時に、Image1Droppedプロシージャを実行します。
20  Image1のMouseLeftButtonDownイベント時に、Image1Largedプロシージャを実行します。
21    Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
22        AddHandler Image1.MouseLeftButtonUp, AddressOf Image1Dropped
23        AddHandler Image1.MouseLeftButtonDown, AddressOf Image1Larged
24    End Sub
25 
26■Image1上でマウスの左ボタンが押された時の処理
27  カーソルを手の形にします。senderオブジェクトの持っているImageの情報を、DirectCastでImage型に変換し、変数myImageで参照します。マウスポインタの左上隅にあるY座標の値をメンバ変数myYPosに格納します。マウスポインタの左上隅にあるX座標の値をメンバ変数myXPosに格納します。Image1上でマウスの左ボタンが押されたため、ブール型の変数myMouseCaptureにTrueを指定しておきます。CaptureMouseメソッドで、Image1のマウスキャプチャを有効にします。
28Private Sub Image1_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Image1.MouseLeftButtonDown
29    Image1.Cursor = Cursors.Hand
30    Dim myImage As Image = DirectCast(sender, Image)
31    myYPos = e.GetPosition(Nothing).Y
32    myXPos = e.GetPosition(Nothing).X
33    myMouseCaputer = True
34    myImage.CaptureMouse()
35    End Sub
36 
37■Image1上でマウスの左ボタンが離された時の処理
38  カーソルを矢印の形にします。senderオブジェクトの持っているImageの情報を、DirectCastでImage型に変換し、変数myImageで参照します。Image1上でマウスの左ボタンが離されたため、ブール型の変数myMouseCaptureにFalseを指定しておきます。ReleaseMouseCaptureメソッドで、Image1のマウスキャプチャを無効にします。Image1がDropされた時のY座標を格納するメンバ変数myYDropPos変数に、現在のマウスポインタのY座標の値を指定します。
39  Private Sub Image1_MouseLeftButtonUp(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Image1.MouseLeftButtonUp
40    Image1.Cursor = Cursors.Arrow
41    Dim myImage As Image = DirectCast(sender, Image)
42    myMouseCaputer = False
43    myImage.ReleaseMouseCapture()
44    myYDropPos = myYPos
45  End Sub
46 
47■Image1をマウスでドラッグして移動した時の処理
48senderオブジェクトの持っているImageの情報を、DirectCastでImage型に変換し、変数myImageで参照します。Image1上でマウスの左が押されている場合に、以下の処理を実行します。
49移動したマウスポインタのY座標の値から、マウスの左ボタンが押された時点で取得されたY座標の値(myYPos)を減算した値を、変数myVerticalに格納します。
50移動したマウスポインタのX座標の値から、マウスの左ボタンが押された時点で取得されたX座標の値(myXPos)を減算した値を、変数myHorizontalに格納します。
51myVerticalの値に、GetValueメソッドで取得したImage1の、CanvasのTopの値を加算した値を、変数myNewTopに格納します。
52myHorizontalの値に、GetValueメソッドで取得したImage1の、CanvasのLeftの値を加算した値を、変数myNewLeftに格納します。
53SetValueメソッドで、Image1のTopとLeftの値に、myNewTopとmyNewLeftの値を指定します。
54現在のマウスポインタのY座標の値を、myYPosメンバ変数に格納しておきます。同様に、現在のマウスポインタのX座標の値を、myXPosメンバ変数に格納しておきます。
55  Private Sub Image1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Image1.MouseMove
56    Dim myImage As Image = DirectCast(sender, Image)
57    If myMouseCaputer = True Then
58        Dim myVertical As Double = e.GetPosition(Nothing).Y - myYPos
59        Dim myHorizontal As Double = e.GetPosition(Nothing).X - myXPos
60        Dim myNewTop As Double = myVertical + DirectCast(myImage.GetValue(Canvas.TopProperty), Double)
61        Dim myNewLeft As Double = myHorizontal + DirectCast(myImage.GetValue(Canvas.LeftProperty), Double)
62        myImage.SetValue(Canvas.TopProperty, myNewTop)
63        myImage.SetValue(Canvas.LeftProperty, myNewLeft)
64        myYPos = e.GetPosition(Nothing).Y
65    myXPos = e.GetPosition(Nothing).X
66  End If
67End Sub
68 
69■Image1上でマウスの左ボタンが離された時の処理
70マウスが離された時のマウスポインタのY座標の値が300より大きかった場合、つまり、Targetキャンバス内にImageがドロップされた時の処理です。
71VisualStateManager.GotoStateメソッドで、画像が縮小するImageSmallの VisualSateを実行します。VisualStateManager.GotoStateメソッドの書式は下記の通りです。
72VisualStateManager.GotoState(状態を遷移させるコントロール,状態名,VisualTransitionを使うかどうかのBoolean値(使用する場合はTrue、それ以外はFalse)
73Targetキャンバス内にある現在のマウスポインタの位置をmyCP変数に格納し、XとY座標の位置を取得します。XとY座標の値を取得したmyCP変数の値を、RippleEffectのCenterプロパティの値に指定します。RippleEffectのストーリーボードを開始します。
74マウスが離された時のマウスポインタのY座標の値が300以外の場合は、画像が元の状態に戻る(拡大する)、ImageLargeのVisualStateを実行します。
75  Private Sub Image1Dropped(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
76    If myYDropPos > 300 Then
77        VisualStateManager.GoToState(Me, "ImageSmall", True)
78        Dim myCP As Point = e.GetPosition(Target)
79        myCP.X = myCP.X / Target.ActualWidth
80        myCP.Y = myCP.Y / Target.ActualHeight
81        myRippleEffect.Center = myCP
82        RippleStoryboard.Begin()
83    Else
84        VisualStateManager.GoToState(Me, "ImageLarge", True)
85    End If
86  End Sub
87 
88■Image1のMouseLeftButtonDownイベント時に実行される処理
89  マウスが押下された時のマウスポインタのY座標の値が、300より小さい場合は(マウスポインタがSourceという名前のCanvas内にあった時(図3参照))、処理を中止します。マウスポインタがSourceという名前のCanvas内にあった時には、画像をドラッグ&ドロップしても画像は何も変化しません。それ以外は、画像が拡大するImageLargeのVisualStateを実行します。
90  Private Sub Image1Larged(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
91    If myYDropPos < 300 Then
92        Exit Sub
93    Else
94        VisualStateManager.GoToState(Me, "ImageLarge", True)
95    End If
96  End Sub
97End Class

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本项目是一个基于SpringBoot开发的华府便利店信息管理系统,使用了Vue和MySQL作为前端框架和数据库。该系统主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的Java学习者,包含项目源码、数据库脚本、项目说明等,有论文参考,可以直接作为毕设使用。 后台框架采用SpringBoot,数据库使用MySQL,开发环境为JDK、IDEA、Tomcat。项目经过严格调试,确保可以运行。如基础还行,可以在代码基础之上进行改动以实现更多功能。 该系统的功能主要包括商品管理、订单管理、用户管理等模块。在商品管理模块中,可以添加、修改、删除商品信息;在订单管理模块中,可以查看订单详情、处理订单状态;在用户管理模块中,可以注册、登录、修改个人信息等。此外,系统还提供了数据统计功能,可以对销售数据进行统计和分析。 技术实现方面,前端采用Vue框架进行开发,后端使用SpringBoot框架搭建服务端应用。数据库采用MySQL进行数据存储和管理。整个系统通过前后端分离的方式实现,提高了系统的可维护性和可扩展性。同时,系统还采用了一些流行的技术和工具,如MyBatis、JPA等进行数据访问和操作,以及Maven进行项目管理和构建。 总之,本系统是一个基于SpringBoot开发的华府便利店信息管理系统,使用了Vue和MySQL作为前端框架和数据库。系统经过严格调试,确保可以运行。如基础还行,可以在代码基础之上进行改动以实现更多功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值