动画

动画是改变控件的一些属性,加一时间元素 。通常结合“呈现变形”,即控件的RenderTransform来完成

一个元素可以完成的作画叫AnimationTimeLine,多个UI元素组合起来的叫Storyboard

简单动画就DoubleAnimationBase派生类用得最多

1.简单线性动画

  几个重要属性:

变化时间(Duration)

变化终点(To属性)

变化幅度(By属性)

变化起点(From属性)

 

    <Grid>

        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="103,72,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="0.5,0.5" Click="button_Click">

            <Button.RenderTransform>

                <TransformGroup> 

                    <TranslateTransform X="0" Y="0" x:Name="tt"/>

 <!--(偏移变形)-->

                    <!--

                    MatrixTransform矩陈变形

                    RotateTransform旋转变形

                    ScaleTransform坐标变形

                    SkewTransform拉伸变形

                    TranslateTransform偏移变形

                    TransformGroup变形组,多个独立变形合成一个变形组,产生复合效果

                    -->

                </TransformGroup>

            </Button.RenderTransform>

        </Button>

    </Grid>

private void button_Click(object sender, RoutedEventArgs e)

        {

            DoubleAnimation daX = new DoubleAnimation();

            DoubleAnimation daY = new DoubleAnimation();

            //若不想每都从0,0坐标开始,则不给From赋值就是从当前开始

            daX.From = 0D;

            daY.From = 0D;

            daX.To = (new Random()).NextDouble() * 300;

            daY.To = (new Random()).NextDouble() * 300;

            Duration dr = new Duration(TimeSpan.FromMilliseconds(300));

            daX.Duration = dr;

            daY.Duration = dr;

            this.tt.BeginAnimation(TranslateTransform.XProperty, daX);

            //如果少了这条,则只是水平移动,没了y轴

            this.tt.BeginAnimation(TranslateTransform.YProperty,daY);

        }

其实就是给好目标的XY坐标值,然后元素向目标点走直线形成的动画

 

2.高级动画控制

就是多了几个属性:

AccelerationRatio 加速速率,介于0.00和1.0之间,与DecclerationRation之和不大于1.0,如模拟汽车启动

DecclerationRation减速速率,介于0.00和1.0之间,与AccelerationRatio 之和不大于1.0,如模拟汽车刹车

SpeedRation动画实际播放速度与正常速度的比值  如快进播放、慢动作

AutoReverse 是否以相反的动画方式从终点值返回起始值 如倒退播放

RepeatBehavior动画的重复行为,取0为不播放,使用double类型值可控制循环次数,取RepeatBehavior.Forever永不停

BeginTime正式开始播放前的等待时间  常用于多个动画协同

EasingFunction缓冲式渐变  如乒乓球弹跳效果

 

以下示例向乒乓球掉在地止弹起3次再停止

 private void button_Click(object sender, RoutedEventArgs e)

        {

            DoubleAnimation daX = new DoubleAnimation();

            DoubleAnimation daY = new DoubleAnimation();

            daX.From = 0D;

            daY.From = 0D;

            BounceEase be = new BounceEase();

            be.Bounces = 52;//跳跃3次

            be.Bounciness = 2;//弹性程序,值越大反弹越低

             

            daY.EasingFunction = be;

            

            daX.To = 2 * 300;

            daY.To = 2 * 300;

            Duration dr = new Duration(TimeSpan.FromMilliseconds(10000));

            daX.Duration = dr;

            daY.Duration = dr;

            this.tt.BeginAnimation(TranslateTransform.XProperty, daX);

            //如果少了这条,则只是水平移动,没了y轴

            this.tt.BeginAnimation(TranslateTransform.YProperty,daY);

        }

 

3.关键帧动画

就是定几个位置,然后指定什么时间到这个点,什么时候到那个点就,程序就会自动在时间内均匀地到达,这样就不需要把几个动作协同了,很是方便

以下为按钮走z字形动画

private void button_Click(object sender, RoutedEventArgs e)

        {

            DoubleAnimationUsingKeyFrames daX = new DoubleAnimationUsingKeyFrames();

            DoubleAnimationUsingKeyFrames daY = new DoubleAnimationUsingKeyFrames();

              

            //总时间长

            Duration dr = new Duration(TimeSpan.FromMilliseconds(10000));

            daX.Duration = dr;

            daY.Duration = dr;

            //创建并添加X关键帧

            LinearDoubleKeyFrame x_kf_1 = new LinearDoubleKeyFrame(200,KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(3000)));

            LinearDoubleKeyFrame x_kf_2 = new LinearDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(5000)));

            LinearDoubleKeyFrame x_kf_3 = new LinearDoubleKeyFrame(200, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(10000)));

            daX.KeyFrames.Add(x_kf_1);

            daX.KeyFrames.Add(x_kf_2);

            daX.KeyFrames.Add(x_kf_3);

            //创建并添加Y关键帧

            LinearDoubleKeyFrame Y_kf_1 = new LinearDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(3000)));

            LinearDoubleKeyFrame Y_kf_2 = new LinearDoubleKeyFrame(180, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(5000)));

            LinearDoubleKeyFrame Y_kf_3 = new LinearDoubleKeyFrame(180, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(10000)));

            daY.KeyFrames.Add(Y_kf_1);

            daY.KeyFrames.Add(Y_kf_2);

            daY.KeyFrames.Add(Y_kf_3);

            this.tt.BeginAnimation(TranslateTransform.XProperty, daX);

            //如果少了这条,则只是水平移动,没了y轴

            this.tt.BeginAnimation(TranslateTransform.YProperty,daY);

        }

 

4.特殊关键帧动画

KeyFrames接收类型除了LinearDoubleKeyFrame(线性变化关键帧),还有:

DiscreteDoubleKeyFrame:不连续变化关键帧

SplineDoubleKeyFrame:样条函数式变化关键帧,目标属性值的变化速率是一条贝赛尔贝线,常用

EasingDoubleKeyFrame:缓冲式变化关键帧

  private void button_Click(object sender, RoutedEventArgs e)

        {

            DoubleAnimationUsingKeyFrames daX = new DoubleAnimationUsingKeyFrames();

            DoubleAnimationUsingKeyFrames daY = new DoubleAnimationUsingKeyFrames();

              

            //总时间长

            Duration dr = new Duration(TimeSpan.FromMilliseconds(10000));

            daX.Duration = dr;

            daY.Duration = dr;

            //创建并添加X关键帧

            SplineDoubleKeyFrame kf = new SplineDoubleKeyFrame();

            kf.KeyTime = KeyTime.FromPercent(1);

            kf.Value = 400;

            //贝赛尔曲线是由始点和终点,再加上两个控制点,控制点的坐标值就会造成直线的拉伸等变形形成的曲线

            KeySpline ks = new KeySpline();

            ks.ControlPoint1 = new Point(0, 1);

            ks.ControlPoint2 = new Point(1, 0);

            kf.KeySpline = ks;

            daX.KeyFrames.Add(kf);

            this.tt.BeginAnimation(TranslateTransform.XProperty, daX);

            //如果少了这条,则只是水平移动,没了y轴

           // this.tt.BeginAnimation(TranslateTransform.YProperty,daY);

        }

最终结果是开始快,中间慢,后半部分又快

4.路径动画

绘制一条路径,然后让目标沿着一条给定的路径移动 ,使用DoubleAnimationUsingPath类。需要一个PathGeometry来指明移动的路径

 <Window.Resources>

        <PathGeometry x:Key="movePath" Figures="M 0,150 C300,-100 300,400 600,120"></PathGeometry>

    </Window.Resources>

 private void button_Click(object sender, RoutedEventArgs e)

        {

            var pg = this.FindResource("movePath") as PathGeometry;

            var du = new Duration(TimeSpan.FromMilliseconds(1000));

            DoubleAnimationUsingPath daX = new DoubleAnimationUsingPath();

            daX.PathGeometry = pg;

            daX.Source = PathAnimationSource.X;(获取坐标值的X值)

            daX.Duration = du;

            var daY = new DoubleAnimationUsingPath();

            daY.PathGeometry = pg;

            daY.Source = PathAnimationSource.Y;(获取坐标值的X值)

            daY.Duration = du;

             

            this.tt.BeginAnimation(TranslateTransform.XProperty, daX);

           this.tt.BeginAnimation(TranslateTransform.YProperty,daY);

        }

//加上下面代码可永远运动

 daX.AutoReverse = true;

            daX.RepeatBehavior = RepeatBehavior.Forever;

            daY.AutoReverse = true;

      daY.RepeatBehavior = RepeatBehavior.Forever;

场景动画

场景动画就是多个元素组成一起的动画,一般是在xaml里写法,后台代码写很是复杂

 

 <Grid>

        <Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="22" Margin="18,39,0,0" VerticalAlignment="Top" Width="254 ">

            <Ellipse Fill="Red" Stroke="Black" Width="20" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" >

                <Ellipse.RenderTransform> 

                        <TranslateTransform x:Name="ttr"/> 

                </Ellipse.RenderTransform>

            </Ellipse>

        </Border>

        <Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="22" Margin="18,61,0,0" VerticalAlignment="Top" Width="254">

            <Ellipse Fill="Green" Stroke="Black" Width="20" HorizontalAlignment="Left"  >

                <Ellipse.RenderTransform>

                    <TranslateTransform x:Name="ttg"/>

                </Ellipse.RenderTransform>

            </Ellipse>

        </Border>

        <Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="22" Margin="18,83,0,0" VerticalAlignment="Top" Width="254">

            <Ellipse Fill="Blue" Stroke="Black" Width="20" HorizontalAlignment="Left" >

                <Ellipse.RenderTransform>

                    <TranslateTransform x:Name="ttb"/>

                </Ellipse.RenderTransform>

            </Ellipse>

        </Border>

        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="18,123,0,0" VerticalAlignment="Top" Width="75" > 

            <Button.Triggers>

                <EventTrigger RoutedEvent="Button.Click">

                    <BeginStoryboard>

                        <Storyboard Duration="0:0:1">

                            <!--红色移动(匀速)-->

                            <DoubleAnimation Duration="0:0:1" To="400" Storyboard.TargetName="ttr" Storyboard.TargetProperty="X"></DoubleAnimation>

                            <!--绿色移动(以加速的方式) -->

                            <DoubleAnimationUsingKeyFrames Duration="0:0:1"  Storyboard.TargetName="ttg" Storyboard.TargetProperty="X">

                                <SplineDoubleKeyFrame  KeyTime="0:0:1" Value="400" KeySpline="1,0,0,1"></SplineDoubleKeyFrame>

                            </DoubleAnimationUsingKeyFrames>

                            <!--蓝色移动(以加速的方式) -->

                            <DoubleAnimationUsingKeyFrames Duration="0:0:1"  Storyboard.TargetName="ttb" Storyboard.TargetProperty="X">

                                <SplineDoubleKeyFrame  KeyTime="0:0:1" Value="400" KeySpline="1,0,0,1"></SplineDoubleKeyFrame>

                            </DoubleAnimationUsingKeyFrames>

                        </Storyboard>

                    </BeginStoryboard>

                </EventTrigger>

            </Button.Triggers>

        </Button>

    </Grid>

原文地址:https://www.cnblogs.com/evemen/p/6239364.html