zoukankan      html  css  js  c++  java
  • 带你一起Piu Piu Piu~

    单刀直入,今天要讲的是自己写的一个WPF动画例子。我们在看下最终效果~
    

    最终效果图
    最近在重看WPF编程宝典2010,在练习第15章动画性能例子时有了些想法。原始例子如下: 
    原始例子 
    原始例子(打包了整个15章的) 
    它是一个可动态改变小球动画帧速的程序~那我能不能让小球一直发射?能不能改变小球的轨迹? 
    所有就有了现在的程序,我们先改变背景和文字(请原谅消音枪的Piu不知道是那个字)这里写图片描述 
    这里写图片描述 
    首先把原来的文本框输入改为Slider,不然输入个文字在点程序就JJ了~然后我们把前台的动画放到后台来实现,每次都创建一个小球。开始动画,结束后在删除~代码如下:

      <Grid>
            <Grid Margin="5">
                <Border BorderBrush="#FFA44545" BorderThickness="2">
                    <Canvas Name="Cvs" ClipToBounds="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#FFB5D7DE">
                        <Canvas.Resources>
                            <Style TargetType="Ellipse">
                                <Setter Property="Fill" Value="Red"></Setter>
                                <Setter Property="Width" Value="10"></Setter>
                                <Setter Property="Height" Value="10"></Setter>
                            </Style>
                        </Canvas.Resources>
                    </Canvas>
                </Border>
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,40" Orientation="Horizontal">
                    <TextBlock Margin="5,0">动画帧率:</TextBlock>
                    <Slider x:Name="Sdr_FrameRate" Width="100" Maximum="100" Minimum="10" Value="60" ToolTip="{Binding Value, ElementName=Sdr_FrameRate}" IsSnapToTickEnabled="True" IsMoveToPointEnabled="True"/>
                </StackPanel>
                <Button Name="btnRepeat"  HorizontalAlignment="Center" VerticalAlignment="Bottom" Content="Piu piu Piu" Padding="5" Click="btnRepeat_Click" Margin="0,0,0,10"></Button>
            </Grid>
        </Grid>
      private void btnRepeat_Click(object sender, RoutedEventArgs e)
            {
                //创建一个圆形的小球
                Ellipse elp = new Ellipse();
                Cvs.Children.Add(elp);
    
                DoubleAnimation leftAnimation = new DoubleAnimation(0, 600, TimeSpan.FromSeconds(5));
    
                leftAnimation.Completed += leftAnimation_Completed;
                //设置动画的帧速
                Timeline.SetDesiredFrameRate(leftAnimation, (int)Sdr_FrameRate.Value);
                //开始宽度位移动画
                elp.BeginAnimation(Canvas.LeftProperty, leftAnimation);
    
                DoubleAnimation topAnimation = new DoubleAnimation(400, 0, TimeSpan.FromSeconds(2.5))
                {
                    DecelerationRatio = 1,
                    AutoReverse = true
                };
                Timeline.SetDesiredFrameRate(topAnimation, (int)Sdr_FrameRate.Value);
                //开始高度位移动画
                elp.BeginAnimation(Canvas.TopProperty, topAnimation);
            }
    
            /// <summary>
            /// 运行完动画后从画布删除小球
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void leftAnimation_Completed(object sender, EventArgs e)
            {
                if (Cvs.Children.Count > 0)
                    Cvs.Children.RemoveAt(0);
            }

    在这里我发现一个问题,当前角度实际是因为高度时间为宽度的一半,所以有曲线的动画。并且动画用的固定的窗体高宽,那么当窗体大小发生变化时就会很奇怪(注意下张图小球消失的地方)~ 
    这里写图片描述 
    所以我们把600,400换成窗体的ActualWidth和ActualHeight(不要使用width和height,因为它们不会随窗体一起改变大小)。这里写图片描述 
    那我们能不能尝试改变的抛物线的弧度呢?(也就是Height动画的时间)假设想使用三种弧度方式固定、递增和随机来动画小球~并且可控制递增的间隔。先来改前台:

              <StackPanel x:Name="stackPanel" HorizontalAlignment="Center" VerticalAlignment="Bottom" Orientation="Horizontal" Margin="0,0,0,66">
                    <TextBlock TextWrapping="Wrap" Text="间隔:"/>
                    <Slider x:Name="Sdr_Interval" Minimum="0.1" Maximum="1" TickFrequency="0.1" Width="100" Margin="5,0,0,0" ToolTip="{Binding Value, ElementName=Sdr_Interval}" IsSnapToTickEnabled="True" IsMoveToPointEnabled="True"/>
                </StackPanel>
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,40" Orientation="Horizontal">
                    <TextBlock>动画角度:</TextBlock>
                    <RadioButton Margin="5,0" Checked="RadioButton_Checked" Tag="1">固定</RadioButton>
                    <RadioButton x:Name="radioButton" Margin="5,0"  Checked="RadioButton_Checked" Unchecked="RadioButton_Unchecked" Tag="2" IsChecked="True">递增</RadioButton>
                    <RadioButton Margin="5,0"  Checked="RadioButton_Checked" Tag="3">随机</RadioButton>
                    <TextBlock Margin="5,0">动画帧率:</TextBlock>
                    <Slider x:Name="Sdr_FrameRate" Width="100" Maximum="100" Minimum="10" Value="60" ToolTip="{Binding Value, ElementName=Sdr_FrameRate}" IsSnapToTickEnabled="True" IsMoveToPointEnabled="True"/>
                </StackPanel>

    第一个好解决我们就使用2.5秒,第二个我们使用1秒每次小球+0.1秒,这样弧度就会增加。效果如下: 
    这里写图片描述

    现在我们发现了些问题,一个是间隔的Slider只和递增有关,切到别的模式应该不显示。所有我们使用Blend加个切换动画。然后小球是在文字的后方的,应该设置下Zindex。最后当切会递增时,它的初始角度应该恢复。OK,我们修改如下~这里写图片描述 
    这里写图片描述 
    这个发现了一个奇怪的问题就是设置间隔Slider的刻度,0.1、0.2都没有问题但0.3就变成了 
    这里写图片描述 
    还有小球是在控件之下文字之上~另外就是我想给Slider指向显示加上前缀文字,如:当前间隔为:0.2。惭愧以上几个问题没解决这里写图片描述如果有人知道,还麻烦告诉我下~ 
    好了,进入最后一项。随机!我打算让小球的大小、时间和颜色全部都随机。代码如下:

                //递增初始时间
                double duraTime = 1;
                //判断模式
                switch (AnageMode)
                {
                    case 1:
                        duraTime = 2.5;
                        break;
                    case 2:
                        duraTime = timeSpan += Sdr_Interval.Value;
                        break;
                    case 3:
                        random = new Random((int)DateTime.Now.Ticks);
                        duraTime = random.Next(1, 10);
                        elp.Height = elp.Width = random.Next(3, 20);
                        elp.Fill = new SolidColorBrush(new Color()
                        {
                            A = 255,
                            R = (byte)random.Next(0, 255),
                            G = (byte)random.Next(0, 255),
                            B = (byte)random.Next(0, 255)
                        });
                        break;
                }
    
                DoubleAnimation topAnimation = new DoubleAnimation(this.ActualHeight, 0, TimeSpan.FromSeconds(duraTime))
                {
                    DecelerationRatio = 1,
                    AutoReverse = true
                };

    真正最终效果如下: 
    这里写图片描述
    其实,你本地全屏看的固定的有尾巴像流星有没有?而降低帧速率时,动画会很卡!你可能发现了随机的时候只有一个方向,而最开始是两个方向的~对,只要我们同时加两个小球,并把动画反过来就好了!最后附上下载,有错误的地方还望指点~这里写图片描述

  • 相关阅读:
    64.Find the Duplicate Number(发现重复数字)
    63.Perfect Squares(完美平方数)
    62.Longest Valid Parentheses(最长的有效括号)
    61.Merge k Sorted Lists(合并k个排序链表)
    60.Median of Two Sorted Arrays(两个排序数组的中位数)
    59.Target Sum(目标和)
    58.Partition Equal Subset Sum(判断一个数组是否可以分成和相等的两个数组)
    57.Queue Reconstruction by Height(按身高重建对列)
    56.Decode String(解码字符串)
    55.Top K Frequent Elements(出现次数最多的k个元素)
  • 原文地址:https://www.cnblogs.com/lan-mei/p/4552871.html
Copyright © 2011-2022 走看看