WinPhone学习笔记(三)——WinPhone的动画

  这段时间又一直赶任务,结果没有去学习,也没有去写博文,这个动画的内容很早就学了,可是一直没把它整理成博文,如今终于有空就弄一下。函数

  开始先讲讲在WinPhone中作动画有两种动画类型,一种是基于帧动画另外一种是基于时间动画。接着介绍的动画都是Silverlight动画,Silverlight动画有用xaml描述,也有用传统的cs代码文件里描述。随后的内容都是以Silverlight动画为主,关键帧动画,动画的触发机制,透视变换动画,优先级。接下来就详细描述各个内容。学习

动画分类

  • 基于帧动画:每调用一次函数则算一帧,在调用一次函数则执行一次变化。
  • 基于时间动画:虽然每次都是在函数上进行调用,可是调用时的变化量是按时间做为自变量。

下面这个例子分别使用了两种类型的动画,动画是文字围绕着中心旋转动画

先是xmal文件spa

 1             <TextBlock Grid.Row="0" Grid.Column="0" Text="Time-base" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5 0.5">
 2                 <TextBlock.RenderTransform>
 3                     <RotateTransform x:Name="rotate1"/>
 4                 </TextBlock.RenderTransform>
 5             </TextBlock>
 6 
 7             <TextBlock Grid.Row="1" Grid.Column="0" Text="Frame-base" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5 0.5">
 8                 <TextBlock.RenderTransform>
 9                     <RotateTransform x:Name="rotate2"/>
10                 </TextBlock.RenderTransform>
11             </TextBlock>

在cs代码文件中就使用了Rendering事件,该事件须要在构造函数中注册设计

CompositionTarget.Rendering += CompositionTarget_Rendering;

CompositionTarget_Rendering方法的定义以下code

1         void CompositionTarget_Rendering(object sender, EventArgs e)
2         {
3             rotate1.Angle = (rotate1.Angle + 0.2) % 360;
4 
5             TimeSpan elapsedTime = DateTime.Now - dtNow;
6             rotate2.Angle = (elapsedTime.TotalMinutes * 360) % 360;
7         }

Rendering事件是在屏幕刷新时触发的,在这个方法里面执行变换,顺其天然则是基于帧的动画,那么利用DateTime的时间差就能够由帧转化成时间了。orm

Silver动画

  这里把动画类型分了两种,用的最多的仍是基于时间动画,我的估计缘由在于基于帧动画其实是依靠屏幕的刷新率。若是遇到不一样的屏幕刷新率,动画播放就会有不一样的效果,可是基于时间动画的话就不会受屏幕刷新率的影响,并且基于帧动画消耗资源也会比较多。对象

  Silverlight动画主要是基于Sotryboard的,使用不一样的Animation类,设置对应的targetName受做用的元素与targetProperty受做用的属性。因为动画变换时受变换的做用类型不同,因此这部分Animation的类有如下几个,DoubleAnimation,ColorAnimation,PointAnimation;这三个子类分别可实现基于数值变化的动画,颜色变换的动画和位置变换的动画。还有几个用于关键帧动画的子类DoubleAnimationUsingKeyFrame,ColorAnimationUsingKeyFrame,PointAnimationUsingKeyFrame,ObjectAnimationUsingKeyFrame,关键帧动画这个先留在后面再说,下面则稍微列举一下简单的Silverlight动画,分别经过在cs实现和经过xmal中中实现blog

先是经过cs实现的,在xaml里添加如下元素。继承

1             <Button Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click" RenderTransformOrigin="0.5 0.5">
2                 <Button.RenderTransform>
3                     <RotateTransform/>
4                 </Button.RenderTransform>
5             </Button>

重点在于这个Button的Click,在Button_Click方法里面定义了动画的内容还有控制了动画的开始

 1         private void Button_Click(object sender, RoutedEventArgs e)
 2         {
 3             Button btn = sender as Button;
 4 
 5             RotateTransform routate = btn.RenderTransform as RotateTransform;
 6             
 7 
 8             DoubleAnimation anima = new DoubleAnimation();
 9             anima.From = -360;
10             anima.To = 360;
11             anima.By = 90;
12             anima.FillBehavior = FillBehavior.Stop;
13             anima.Duration = new Duration(TimeSpan.FromSeconds(0.5));
14             anima.RepeatBehavior = new RepeatBehavior(TimeSpan.FromSeconds(5));
15             anima.AutoReverse = true;
16             
17             Storyboard.SetTarget(anima, routate);
18             Storyboard.SetTargetProperty(anima, new PropertyPath(RotateTransform.AngleProperty));
19             
20 
21             Storyboard storyboard = new Storyboard();
22             storyboard.Children.Add(anima);
23             storyboard.AutoReverse = true;
24             storyboard.Duration = new Duration(TimeSpan.FromSeconds(0.25));
25             storyboard.Begin();
26         }

代码分了三截,第一截是定义了动画的细节,第二截是定义了动画整个变换的过程当中受做用的变化属性,在这里而已就是按钮的角度随着动画的执行而改变,最后是StoryBoard的构造和播放StoryBoard里面的全部动画,一个StoryBoard就相似于一个场景,场景里面能够有不少个演员(各个Animation类)按照剧本上的安排(开发人员定义的动画内容)来演戏(执行动画)。上面有涉及到Animation类和StoryBoard类的几个属性,

  • FillBehavior:表示动画执行完毕以后受做用对象的状态,简单理解就是指维持在动画执行完毕以后的那个值仍是恢复到动画开始时的那个值;
  • Duration:整个动画过程所花费的时间;
  • RepeatBehavior:动画重复播放的次数,
  • AutoReverse:是否让动画重复播放。

这些属性都是Animation类和StoryBoard类共有的,由于他们都是TimeLine的属性,而这些属性都是TimeLine的属性。这些属性在Animation中设置是只对一个动画受影响,在StoryBoard里设置就对整个StoryBoard里的全部动画都影响。

下面也稍介绍用xmal的方式,也是有这么的一个按钮

            <Button Content="Button2" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click_1" RenderTransformOrigin="0.5 0.5">
                <Button.RenderTransform>
                    <RotateTransform x:Name="rotate3" />
                </Button.RenderTransform>
            </Button>

动画就以页面资源的形式

    <phone:PhoneApplicationPage.Resources>
        <Storyboard x:Name="storyboard1">
            <DoubleAnimation Storyboard.TargetName="rotate3"
                             Storyboard.TargetProperty="Angle"
                              From="0" To="360" Duration="0:0:0.5" RepeatBehavior="3"/>
        </Storyboard>
    </phone:PhoneApplicationPage.Resources>

这里涉及到的属性还有设计与上面用cs的相比起来仍是同样的,最有在按钮的Click事件控制动画的播放

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            storyboard1.Begin();
        }

关键帧动画

  对于上面说起实现的动画动做可能稍微有点大,而Silverlight动画里面也能够实现关键帧动画,从而控制动画过程当中的每一个细节。上面介绍的各个UsingKeyFrame的Animation类中,包含了几个KeyFrame结尾的子元素来控制动画的变换中的自变量,这几个子元素分别以下

  • DiscreteXXXKeyFrame:跳跃到特定位置的动画;
  • LinearXXXKeyFrame:线性动画;
  • SplineXXXKeyFrame:加速或减速的变速动画;
  • EasingXXXKeyFrame:渐变函数动画。

上面的这几个元素都是带XXX,就是指对那几种不一样的UsingKeyFrame类都有这几个子元素,而Double的就是DiscreteDoubleKeyFrame,Color的就是DiscreteColorKeyFrame。而这四种类型中Discrete和Linear不做展开介绍了。可是KeyFrame的这类元素都有两个比较关键的属性KeyTime和value,value是目标值,完成这一帧所达到的值,keyTime则是完成这个帧时的时间。

  SplineXXXKeyFrame变速动画,这类动画则是利用贝塞尔曲线做为动画的变化速度来控制动画播放,贝塞尔曲线是由两个控制点来控制整条曲线的形状,这两个属性是KeySpline类型的两个成员ControlPoint1和ControlPoint2,而这个KeySpline也是SplineXXXKeyFrame的一个属性成员。

  EasingXXXKeyFrame 渐变函数动画,这个渐变函数若是不是实践过的话也不知道是什么回事,这类的动画是按照各类渐变函数来决定整个动画变换中的变化值,渐变函数的基类是EasingFunctionBase,它的各个子类就是各类具体的渐变函数,对渐变函数动画的动画效果影响因素有两个一个是渐变函数的类型,另外一个是插值模式,动画的插值模式经过EaseMode设置,它是一个枚举,有EaseIn,EaseOut,EaseInOut三种,而渐变函数则是由EasingFunction属性设置,渐变函数的类型有11种,这个能够访问MSDN EasingModel枚举那一页来看出各个渐变函数的图象。

动画的触发

  上面列举了的Silverlight动画都是基于StoryBoard的,动画开始是经过Begin()方法的调用,以前调用Begin()方法是在按钮的Click事件里面的,可是能够在元素加载的时候触发这些动画,这里能够用上Silverlight的触发器,各个元素均可以在xmal中使用上这个触发器来执行动画,如同下面格式

                <各类容器.Triggers>
                    <EventTrigger>
                        <BeginStoryboard>
                            <Storyboard >
                                <!—各类的Animation--!>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </各类容器.Triggers>

透视变换

  上面的动画都是用了元素的RenderTransform,作出来的动画都是二位的仿射变换,可是要作到有三维立体效果的透视变换,那就须要用到元素的另一个属性Projection,此次受做用的属性是RotationX(RotationY或者RotationZ),PlaneProjection对象有CenterOfRotationX,CenterOfRotationY,CenterOfRotationZ属性来设置旋转轴的中心,xyz表明坐标系中的三条坐标轴,范围是0到1,0是元素的起始位置,1是元素的结束位置,0.5则是中心。GlobalOffsetX,GlobalOffsetY,GlobalOffsetZ是整个对象与对应的坐标轴偏移像素,这只是一个变换的目标对象,仍然可使用以前说的Silverlight动画,例以下面的把一个文本三维旋转的

            <TextBlock Name="txtblk"
                       Grid.Row="0" Grid.Column="0"
                       Grid.ColumnSpan="3"
                       Text="ROTATE"
                       FontSize="{StaticResource PhoneFontSizeHuge}"
                       Foreground="{StaticResource PhoneAccentBrush}"
                       VerticalAlignment="Center"
                       HorizontalAlignment="Center">
                <TextBlock.Projection>
                    <PlaneProjection x:Name="planeProjection"
                                     CenterOfRotationX="1" CenterOfRotationY="1"
                                     GlobalOffsetX="-100"/>
                </TextBlock.Projection>
            </TextBlock>
    <phone:PhoneApplicationPage.Resources>
        <Storyboard x:Name="rotateX">
            <DoubleAnimation Storyboard.TargetName="planeProjection"
                             Storyboard.TargetProperty="RotationX"
                             From="0" To="360" Duration="0:0:5"/>
        </Storyboard>

        <Storyboard x:Name="rotateY">
            <DoubleAnimation Storyboard.TargetName="planeProjection"
                             Storyboard.TargetProperty="RotationY"
                             From="0" To="360" Duration="0:0:5"/>
        </Storyboard>

        <Storyboard x:Name="rotateZ">
            <DoubleAnimation Storyboard.TargetName="planeProjection"
                             Storyboard.TargetProperty="RotationZ"
                             From="0" To="360" Duration="0:0:5"/>
        </Storyboard>
    </phone:PhoneApplicationPage.Resources>

属性的优先级

  最后说起一下的优先级的问题,动画自己也是在设置元素的属性,那么对元素属性设置方式多种多样,整个优先级顺序从大到小分别是 属性的强制保护(属性设置后的一些约束)>动画>本地设置(单纯设置属性)>样式设置>主题风格>属性继承

相关文章
相关标签/搜索