WPF案例(二)模拟Apple OS 界面前后180度反转

    我们在设计应用程序界面的时候,为了充分利用界面空间,住住需要灵活的界面布局方式,比如可以在界面正面空间上定义一个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中通过MeshGeometry3D元素的Positions 属性描述几何模型的各个顶点,TriangleIndices 属性描述以怎样的顺序来连接三个顶点以构成一个三角形的基本三维基元,通过Positions 和TriangleIndices 的组合,我们就可以创建出复杂的几何3D模型

   定义了3D模型后,还需要对3D模型的每一面应用纹理,以使3D模型可见,Material元素被设计用来描述3D模型的纹理,在本例中使用2D的VisualBrush填充3D模型的Material

   在这个示例中实现的是正反面反转,因此需要分别定义模型正反面的Material,在GeometryModel3D元素中,由BackMaterial 属性描述GeometryModel3D元素的背面Material,由于背面Material位于照相机的另一面,是不可见的,必须使3D模型180度反转后,才可使照相机能投影到BackMaterial,于是这里使用了RotateTransform3D元素180度反转GometryModel3D

GeomertyModel3D的定义
 1  <GeometryModel3D>
 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场景中去,通过显示隐藏相关元素一样可以实现反转界面的动画效果

Storyboard的定义
 1 <Storyboard x:Key="FrontClick">
 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"  
                            oryboard.TargetProperty="(PerspectiveCamera.Position)" />
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>
posted @ 2010-09-02 11:24  顾点点  阅读(4431)  评论(4编辑  收藏  举报