我们在设计应用程序界面的时候,为了充分利用界面空间,住住需要灵活的界面布局方式,比如可以在界面正面空间上定义一个Chart,背面空间上定义一个GridView,通过在Chart上鼠标双击,控件180度旋转后向用户显示出界面背面的GridView,通过在GridView上双击鼠标,控件再一次平滑的180度旋转向用户显示正面的Chart
这个例子就是使用Wpf模拟Apple OS 实现一个包含正反面元素的控件以Y轴为坐标前后180翻转的动画效果,在这里为方便示例,在正反面各以一个Image来表示,在每一面的Image上双击鼠标,Image将180度反转,显示出背面的另一幅Image,下面是示例界面的缩略图,有兴趣的朋友可以下载源码
在这个示例中主要采用了GeometryModel3D和VisualBrush这两个元素,GeometryModel3D用来在3D场景中建立几何模型,在Wpf中,任何复杂的3D模型最终都是由多个基本基元组成的,最小的基本基元被定义为由三个顶点连线组成的三角形,几何模型的每一面就是由多个这样的三角形的三维基元组合而成的。
在Wpf中通过
2 < GeometryModel3D.Geometry >
3 < MeshGeometry3D TriangleIndices ="0,1,2 2,3,0" TextureCoordinates ="0,1 1,1 1,0 0,0"
4 Positions ="-0.5,-0.5,0 0.5,-0.5,0 0.5,0.5,0 -0.5,0.5,0" />
5 </ GeometryModel3D.Geometry >
6 < GeometryModel3D.Material >
7 < DiffuseMaterial >
8 < DiffuseMaterial.Brush >
9 < VisualBrush Visual =" {Binding ElementName=frontHost} " />
10 </ DiffuseMaterial.Brush >
11 </ DiffuseMaterial >
12 </ GeometryModel3D.Material >
13 < GeometryModel3D.BackMaterial >
14 < DiffuseMaterial >
15 < DiffuseMaterial.Brush >
16 < VisualBrush Visual =" {Binding ElementName=backHost} " >
17 < VisualBrush.RelativeTransform >
18 < ScaleTransform ScaleX ="-1" CenterX ="0.5" />
19 </ VisualBrush.RelativeTransform >
20 </ VisualBrush >
21 </ DiffuseMaterial.Brush >
22 </ DiffuseMaterial >
23 </ GeometryModel3D.BackMaterial >
24 < GeometryModel3D.Transform >
25 < RotateTransform3D >
26 < RotateTransform3D.Rotation >
27 < AxisAngleRotation3D x:Name ="rotate" Axis ="0,1,0" Angle ="0" />
28 </ RotateTransform3D.Rotation >
29 </ RotateTransform3D >
30 </ GeometryModel3D.Transform >
31 </ GeometryModel3D >
对GometryModel3D的前后反转定义动画,在Wpf中,Viewport2DVisual3D用来在3D场景中宿主2D控件,因此只要把Image宿主在Viewport2DVisual3D中,就可以在直接在3D场景中反转Image,但这不是一个好的方法,因为如果宿主一个比较复杂,比较"重"的2D控件到Viewport2DVisual3D,并在3D场景中对它应用动画,将使动画的画面出现停顿,因此一个好的解决方法是用VisualBrush将2D控件的实时图像刷新到GometryModel3D的表面Material上,这样可使2D控件不用直接参于到3D场景中去,通过显示隐藏相关元素一样可以实现反转界面的动画效果
2 < ObjectAnimationUsingKeyFrames Storyboard.TargetName ="Viewport3D"
3 Storyboard.TargetProperty ="Visibility" >
4 < DiscreteObjectKeyFrame KeyTime ="0:0:0" Value =" {x:Static Visibility.Visible} " />
5 < DiscreteObjectKeyFrame KeyTime ="0:0:1.1" Value =" {x:Static Visibility.Hidden} " />
6 </ ObjectAnimationUsingKeyFrames >
7 < ObjectAnimationUsingKeyFrames Storyboard.TargetName ="backWrapper"
8 Storyboard.TargetProperty ="Visibility" >
9 < DiscreteObjectKeyFrame KeyTime ="0:0:1" Value =" {x:Static Visibility.Visible} " />
10 </ ObjectAnimationUsingKeyFrames >
11 < ObjectAnimationUsingKeyFrames Storyboard.TargetName ="frontWrapper"
12 Storyboard.TargetProperty ="Visibility" >
13 < DiscreteObjectKeyFrame KeyTime ="0:0:0.05" Value =" {x:Static Visibility.Hidden} " />
14 </ ObjectAnimationUsingKeyFrames >
15 < DoubleAnimation To ="0" Duration ="0:0:0.05" Storyboard.TargetName ="frontWrapper"
16 Storyboard.TargetProperty ="Opacity" />
17 < DoubleAnimation BeginTime ="0:0:1.05" Duration ="0:0:0.05" To ="1"
18 Storyboard.TargetName ="backWrapper" Storyboard.TargetProperty ="Opacity" />
19 < Point3DAnimation To ="0,0,1.1" From ="0,0,0.5" BeginTime ="0:0:0.05" Duration ="0:0:0.5"
20 AutoReverse ="True" DecelerationRatio ="0.3" Storyboard.TargetName ="camera"
21 Storyboard.TargetProperty ="(PerspectiveCamera.Position)" />
22 < DoubleAnimation From ="0" To ="180" AccelerationRatio ="0.3" DecelerationRatio ="0.3"
23 BeginTime ="0:0:0.05" Duration ="0:0:1" Storyboard.TargetName ="rotate" Storyboard.TargetProperty ="Angle" />
24 </ Storyboard >
25 < Storyboard x:Key ="BackClick" >
26 < ObjectAnimationUsingKeyFrames Storyboard.TargetName ="Viewport3D"
27 Storyboard.TargetProperty ="Visibility" >
28 < DiscreteObjectKeyFrame KeyTime ="0:0:0" Value =" {x:Static Visibility.Visible} " />
29 < DiscreteObjectKeyFrame KeyTime ="0:0:1.1" Value =" {x:Static Visibility.Hidden} " />
30 </ ObjectAnimationUsingKeyFrames >
31 < ObjectAnimationUsingKeyFrames Storyboard.TargetName ="frontWrapper"
32 Storyboard.TargetProperty ="Visibility" >
33 < DiscreteObjectKeyFrame KeyTime ="0:0:1" Value =" {x:Static Visibility.Visible} " />
34 </ ObjectAnimationUsingKeyFrames >
35 < ObjectAnimationUsingKeyFrames Storyboard.TargetName ="backWrapper"
36 Storyboard.TargetProperty ="Visibility" >
37 < DiscreteObjectKeyFrame KeyTime ="0:0:0.05" Value =" {x:Static Visibility.Hidden} " />
38 </ ObjectAnimationUsingKeyFrames >
39 < DoubleAnimation To ="0" Duration ="0:0:0.05" Storyboard.TargetName ="backWrapper"
40 Storyboard.TargetProperty ="Opacity" />
41 < DoubleAnimation BeginTime ="0:0:1.05" Duration ="0:0:0.05"
42 Storyboard.TargetName ="frontWrapper" Storyboard.TargetProperty ="Opacity" />
43 < Point3DAnimation To ="0,0,1.1" From ="0,0,0.5" BeginTime ="0:0:0.05"
44 Duration ="0:0:0.5" AutoReverse ="True" DecelerationRatio ="0.3" Storyboard.TargetName ="camera"
45 < DoubleAnimation From ="180" To ="360" AccelerationRatio ="0.3"
46 DecelerationRatio ="0.3" BeginTime ="0:0:0.05" Duration ="0:0:1"
47 Storyboard.TargetName ="rotate" Storyboard.TargetProperty ="Angle" />
48 </ Storyboard >