wpf-绘图-动画基础

基础知识

用来制作动画的属性必须是依赖属性。动画实际是一段时间内各种属性值的连续变化。
简单动画称为AnimationTimeline,复杂动画需要多个UI元素合作完成,称为Storyboard。
在这里插入图片描述
几乎针对每个可用的数据类型,都准备了相应的动画派生类。
在这里插入图片描述
不是所有抽象基类都有这三个的,有的会缺。

简单线性动画

四要素:

  • 变化起点:From,如果没有指定,则以变化目标属性的当前值为起点
  • 变化终点:To,如果没有指定,则以上次动画的终点或默认值为变化终点
  • 变化幅度:By,如果同时指定了变化终点,变化幅度将被忽略
  • 变化时间:Duration,必须指定,数据类型也是Duration

实例:按钮移动

每次点击按钮,按钮会从(0,0)也就是窗体左上角向右下角移动,x,y都不超过300,完成运动的时长是300ms。
如果不指定的话,会在上一个终点的基础上跳。

前台

    <Grid>
        <Button Content="Move!" HorizontalAlignment="Left" VerticalAlignment="Top"
                Width="60" Height="60" Click="Button_Click">
            <Button.RenderTransform>
                <TranslateTransform x:Name="tt" X="0" Y="0"/>
            </Button.RenderTransform>
        </Button>
    </Grid>

后台

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            DoubleAnimation daX = new DoubleAnimation();
            DoubleAnimation daY = new DoubleAnimation();
            //指定起点
            daX.From = 0D;
            daY.From = 0D;
            //指定终点
            Random r = new Random();
            // NextDouble是产生0~1的double
            daX.To = r.NextDouble() * 300;
            daY.To = r.NextDouble() * 300;
            Console.WriteLine(daX.To);
            //指定时长
            Duration duration = new Duration(TimeSpan.FromMilliseconds(300));//返回指定的毫秒数
            daX.Duration = duration;
            daY.Duration = duration;
            // 动画的主体是TranslateTransform,非button
            this.tt.BeginAnimation(TranslateTransform.XProperty, daX); // XProperty和YProperty都是依赖属性
            this.tt.BeginAnimation(TranslateTransform.YProperty, daY);
        }

如果不指定起点,不指定终点,只令

daX.By = 100D;
daY.By = 100D;

那么按钮每次会往右下角移动。

如果希望调整Button的宽度或高度(也是Double类型),那也是上面类似的操作,只是要影响的是Button.WidthProperty和Button.HeightProperty (测试没通过,以后我再补充吧)

高级动画

  • AccelerationRatio,加速速率,[0, 1],与DecelerationRatio之和不大于1.0, 模拟汽车启动
  • DecelerationRatio,减速速率,[0, 1],模拟汽车刹车
  • SpeedRatio,动画实际播放速度与正常速度的比值,快进播放、慢动作
  • AutoReverse,是否以相反的动画方式从终止值返回起始值,倒退播放
  • RepearBehavior,动画的重复行为,0表示不播放,double值控制循环次数,RepeatBehavior.Forever表示永远循环,循环播放
  • BeginTime,正式开始播放前的等待时间,多个动画之前的协同
  • EasingFunction,缓冲式渐变,乒乓球弹跳效果(取值是IEasingFunction接口,派生类很多)

实例:按钮弹跳

在这里插入图片描述

        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 = 3;//弹跳3次
            be.Bounciness = 3;//弹性程度,值越大反弹越低
            daY.EasingFunction = be;
            //指定终点
            daX.To = 300;
            daY.To = 300;
            //指定时长
            Duration duration = new Duration(TimeSpan.FromMilliseconds(2000));//返回指定的毫秒数
            daX.Duration = duration;
            daY.Duration = duration;
            // 动画的主体是TranslateTransform,非button
            this.tt.BeginAnimation(TranslateTransform.XProperty, daX);
            this.tt.BeginAnimation(TranslateTransform.YProperty, daY);
        }

关键帧动画

动画是UI元素属性连续改变所产生的视觉效果。属性的每次变化都会产生一个新的画面,这个新画面称为一“帧”。单位时间内播放的帧数越多,动画的效果越细致。前面的简单动画只设置了起点和终点,之间的动画帧是由程序计算并绘制出来的,程序猿无法控制。关键帧动画允许程序猿为一段动画设置几个里程碑,当动画执行到里程碑所在的时间点时,被动画控制的属性也必须达到设定的值。这种里程碑就是关键帧。

实例:按钮Z形移动

要求button在被单击后用900ms从左上角移动至右下角,走Z字形(可以几段简单动画拼一起,但是一旦需求改动,不好改)。
在这里插入图片描述

    <Grid>
        <Button Content="Move" VerticalAlignment="Top" HorizontalAlignment="Left"
                Width="80" Height="80" Click="Button_Click">
            <Button.RenderTransform>
                <TranslateTransform x:Name="tt" X="0" Y="0"/>
            </Button.RenderTransform>
        </Button>
    </Grid>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            DoubleAnimationUsingKeyFrames dakX = new DoubleAnimationUsingKeyFrames();
            DoubleAnimationUsingKeyFrames dakY = new DoubleAnimationUsingKeyFrames();
            //设置动画总时长
            dakX.Duration = new Duration(TimeSpan.FromMilliseconds(900));
            dakY.Duration = new Duration(TimeSpan.FromMilliseconds(900));
            //为了x
            LinearDoubleKeyFrame x_kf_1 = new LinearDoubleKeyFrame();
            LinearDoubleKeyFrame x_kf_2 = new LinearDoubleKeyFrame();
            LinearDoubleKeyFrame x_kf_3 = new LinearDoubleKeyFrame();
            x_kf_1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300)); //FromTimeSpan是绝对时间
            x_kf_1.Value = 200;
            x_kf_2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(600));
            x_kf_2.Value = 0;
            x_kf_3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(900));
            x_kf_3.Value = 200;
            //添加关键帧
            dakX.KeyFrames.Add(x_kf_1);
            dakX.KeyFrames.Add(x_kf_2);
            dakX.KeyFrames.Add(x_kf_3);
            //为了y
            LinearDoubleKeyFrame y_kf_1 = new LinearDoubleKeyFrame();
            LinearDoubleKeyFrame y_kf_2 = new LinearDoubleKeyFrame();
            LinearDoubleKeyFrame y_kf_3 = new LinearDoubleKeyFrame();
            y_kf_1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300)); //FromTimeSpan是绝对时间
            y_kf_1.Value = 0;
            y_kf_2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(600));
            y_kf_2.Value = 180;
            y_kf_3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(900));
            y_kf_3.Value = 180;
            dakY.KeyFrames.Add(y_kf_1);
            dakY.KeyFrames.Add(y_kf_2);
            dakY.KeyFrames.Add(y_kf_3);
            // 添加
            this.tt.BeginAnimation(TranslateTransform.XProperty, dakX);
            this.tt.BeginAnimation(TranslateTransform.YProperty, dakY);
        }

说明:KeyTime.FromPercent()是以百分比计算相对时间点的,全长是100%。这样避免了延长时间时需要再改绝对值。可以只改Duration。
如果使用KeyTime.FromPercent(0.33), 0.66, 1.0,也可以有同样的效果。

特殊关键帧

DoubleAnimationUsingKeyFrames的属性KeyFrames的数据类型是DoubleKeyFrameCollection,可以接收元素类型为DoubleKeyFrame的对象。DoubleKeyFrame是一个抽象类,派生类有:

  • LinearDoubleKeyFrame:目标属性值是均匀变化的
  • DiscreteDoubleKeyFrame:目标属性值的变化是跳跃性的、跃迁的
  • SplineDoubleKeyFrame:目标属性值的变化速率是一条贝塞尔曲线(常用)
  • EasingDoubleKeyFrame:目标属性值以某种缓冲形式变化

SplineDoubleKeyFrame实例

它的贝塞尔曲线有两个控制点ControlPoint1和ControlPoint2,如果这两点的自己的横纵坐标值相等,如(0.5,0.5)这样,那么贝塞尔曲线是直线,则与LinearDoubleKeyFrame等价。
在这里插入图片描述

        private void Button_Click(object sender, RoutedEventArgs e) {
            DoubleAnimationUsingKeyFrames dakX = new DoubleAnimationUsingKeyFrames();
            dakX.Duration = new Duration(TimeSpan.FromMilliseconds(1000));
            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;
            dakX.KeyFrames.Add(kf);
            this.tt.BeginAnimation(TranslateTransform.XProperty, dakX);
        }

说明:移动起来还是挺有动感的,可以试试。常用SplineDoubleKeyFrame代替LinearDoubleKeyFrame。

路径动画

让目标对象沿一条给定的路径移动。使用DoubleAnimationUsingPath类。需要一个PathGeometry指明路径。Source取值PathAnimationSource.X的话,表示动画关注每一点横坐标的变化,如果是PathAnimationSource.Y则关注每一点纵坐标的变化,如果是.Angle则关注每一点处切线方向的变化。

实例:button沿一条贝塞尔曲线做波浪线形运动

    <Grid x:Name="LayoutRoot">
        <Grid.Resources>
            <!--移动路径-->
            <PathGeometry x:Key="movingPath" Figures="M 0,150 C300,-100 300,400 600,120"/>
        </Grid.Resources>
        <Button Content="Move" HorizontalAlignment="Left" VerticalAlignment="Top"
                Width="80" Height="80" Click="Button_Click">
            <Button.RenderTransform>
                <TranslateTransform x:Name="tt" X="0" Y="0"/>
            </Button.RenderTransform>
        </Button>
    </Grid>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            PathGeometry pg = this.LayoutRoot.FindResource("movingPath") as PathGeometry;
            Duration duration = new Duration(TimeSpan.FromMilliseconds(600));
            //创建动画
            DoubleAnimationUsingPath dapX = new DoubleAnimationUsingPath();
            dapX.PathGeometry = pg;
            dapX.Source = PathAnimationSource.X;
            dapX.Duration = duration;
            // y
            DoubleAnimationUsingPath dapY = new DoubleAnimationUsingPath();
            dapY.PathGeometry = pg;
            dapY.Source = PathAnimationSource.Y;
            dapY.Duration = duration;
            //执行
            this.tt.BeginAnimation(TranslateTransform.XProperty, dapX);
            this.tt.BeginAnimation(TranslateTransform.YProperty, dapY);
        }

如果加上下面几句就能来回来去地跑了:

            dapX.AutoReverse = true;
            dapX.RepeatBehavior = RepeatBehavior.Forever;
            dapY.AutoReverse = true;
            dapY.RepeatBehavior = RepeatBehavior.Forever;

场景

场景就是并行执行一组动画。选好触发时机。一般用前端设计,后台设计很麻烦。

实例:三只小球同时运动

在这里插入图片描述
点击按钮,三个小球会移动过去。

    <Grid Margin="6">
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="60"/>
        </Grid.ColumnDefinitions>
        <Border BorderBrush="Gray" BorderThickness="1" Grid.Row="0">
            <Ellipse x:Name="ballR" Height="48" Width="48" Fill="Red"
                     HorizontalAlignment="Left">
                <Ellipse.RenderTransform>
                    <TranslateTransform x:Name="ttR"/>
                </Ellipse.RenderTransform>
            </Ellipse>
        </Border>
        <Border BorderBrush="Gray" BorderThickness="1,0,1,1" Grid.Row="1">
            <Ellipse x:Name="ballG" Height="48" Width="48" Fill="LawnGreen"
                     HorizontalAlignment="Left">
                <Ellipse.RenderTransform>
                    <TranslateTransform x:Name="ttG"/>
                </Ellipse.RenderTransform>
            </Ellipse>
        </Border>
        <Border BorderBrush="Gray" BorderThickness="1,0,1,1" Grid.Row="2">
            <Ellipse x:Name="ballB" Height="48" Width="48" Fill="Blue"
                     HorizontalAlignment="Left">
                <Ellipse.RenderTransform>
                    <TranslateTransform x:Name="ttB"/>
                </Ellipse.RenderTransform>
            </Ellipse>
        </Border>
        <Button Content="Button" Grid.Column="1" Grid.RowSpan="3">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard Duration="0:0:0.6">
                            <!--红色小球动画-->
                            <DoubleAnimation Duration="0:0:0.6" To="400"
                                             Storyboard.TargetName="ttR"
                                             Storyboard.TargetProperty="X"/>
                            <!--绿色小球动画-->
                            <DoubleAnimationUsingKeyFrames Duration="0:0:0.6"
                                                           Storyboard.TargetName="ttG"
                                                           Storyboard.TargetProperty="X">
                                <SplineDoubleKeyFrame KeyTime="0:0:0.6" Value="400"
                                                      KeySpline="1,0,0,1"/>
                            </DoubleAnimationUsingKeyFrames>
                            <!---->
                            <DoubleAnimationUsingKeyFrames Duration="0:0:0.6"
                                                           Storyboard.TargetName="ttB"
                                                           Storyboard.TargetProperty="X">
                                <SplineDoubleKeyFrame KeyTime="0:0:0.6" Value="400"
                                                      KeySpline="0,1,1,0"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>
    </Grid>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: "WPF-强大的图表.zip"是一个WPFA强大的图表库,可以用于创建各种类型的图表和数据可视化。这个库具有很多有用的功能和特性,使它成为开发人员首选的工具之一。 首先,它提供了丰富的图表类型,包括线条图、面积图、柱形图、饼图等等。无论是展示数据趋势、比较数据之间的关系,还是显示数据的分布,都可以使用该库来轻松创建出美观且具有交互性的图表。 其次,它支持数据的实时更新和动画效果。开发人员可以通过简单的代码,实现数据的实时更新和动画效果,使图表更加生动和动态。 此外,该库还提供了丰富的自定义选项,使开发人员能够根据自己的需求定制图表的外观和行为。可以调整图表的颜色、字体、背景等,使其与应用程序的风格一致。同时,还可以通过添加标签、工具提示等增加交互性和信息展示的功能。 最后,该库还具有良好的性能和稳定性。它采用了高效的绘图技术和数据处理算法,能够处理大量数据和复杂的图表。同时,它也经过了严格的测试和验证,保证在各种环境下都能稳定运行。 总之,"WPF-强大的图表.zip"是一个强大且易于使用的图表库,可以帮助开发人员轻松创建出各种类型的图表和数据可视化。无论是个人开发者还是企业应用开发者,都可以通过使用该库,提升应用程序的用户体验和数据展示效果。 ### 回答2: wpf-强大的图表.zip 是一个 WPF(Windows Presentation Foundation) 的图表库,提供了强大的图表功能。WPF 是一种用于创建 Windows 桌面应用程序的技术,它提供了丰富的用户界面元素和视觉效果,能够创建出漂亮、灵活和交互性强的应用程序。 这个图表库的强大之处在于它提供了多种类型的图表,包括饼图、柱状图、折线图、散点图等,可以满足不同需求的数据可视化要求。通过使用这个库,开发人员可以轻松创建出直观、美观的图表,使得数据更加易于理解和分析。 此外,这个库还提供了丰富的图表定制和交互功能。开发人员可以自定义图表的样式、颜色和标签,以适应不同的设计需求。还可以添加交互功能,比如通过鼠标点击或拖拽来实现数据筛选、数据比较等功能。这些功能使得使用者可以更加灵活地探索和分析数据。 值得一提的是,这个库还提供了一些额外的功能,如数据绑定、动画效果等。数据绑定可以方便地将图表与数据源进行绑定,实时更新图表内容。动画效果可以为图表增添一些动态效果,增强用户的体验。 总之,wpf-强大的图表.zip 是一个功能丰富、易于使用和定制的图表库,适用于需要数据可视化的 WPF 应用程序开发。无论是做数据分析、报表生成还是展示数据趋势,使用这个库可以轻松创建出漂亮、交互性强的图表,提升应用程序的用户体验。 ### 回答3: WPF-强大的图表.zip是一个压缩文件,包含了使用WPF(Windows Presentation Foundation)技术开发的强大图表控件库。WPF是微软推出的一种用于创建丰富、灵活、交互性高的应用程序的技术,它采用XAML(Extensible Application Markup Language)语言描述界面,支持数据绑定、动画效果等丰富功能。 在WPF-强大的图表.zip中,我们可以找到多种类型的图表控件,比如折线图、柱状图、饼图等。这些图表控件支持灵活的自定义配置,可以通过数据绑定将数据源与图表进行关联,实现数据的可视化展示。同时,这些图表控件还支持动画效果,能够给用户提供更加生动、直观的数据展示体验。 WPF-强大的图表.zip还包含了一些示例代码和文档,帮助开发人员快速上手使用这些图表控件。开发人员可以参考示例代码,理解如何使用这些图表控件创建各种不同类型的图表,并且通过文档来学习控件的使用方法和属性配置。 总之,WPF-强大的图表.zip提供了一套功能强大、灵活易用的图表控件库,方便开发人员在WPF应用程序中实现各种各样的数据可视化需求。无论是企业数据分析,还是个人数据展示,这些图表控件都能够帮助开发人员快速构建出美观、交互性强的图表界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值