• WPF中动画教程(DoubleAnimation的基本使用)


    实现效果

    今天以一个交互式小球的例子跟大家分享一下wpf动画中DoubleAnimation的基本使用。该小球会移动到我们鼠标左键或右键点击的地方。

    该示例的实现效果如下所示:

    实现效果

    页面设计

    xaml如下所示:

    
        
            
                
            
        
    
    

    就是在DockPanel中包含一个Border,在Border中包含一个圆形。

    页面设计的效果如下所示:

    image-20240401095600816

    一些设置

    相关设置的cs代码如下所示:

       public partial class MainWindow : Window
     {
         private readonly TranslateTransform _interactiveTranslateTransform;
         public MainWindow()
         {
             InitializeComponent();
    
             _interactiveTranslateTransform = new TranslateTransform();
    
             _interactiveEllipse.RenderTransform =
                 _interactiveTranslateTransform;
    
             _containerBorder.MouseLeftButtonDown +=
                border_mouseLeftButtonDown;
             _containerBorder.MouseRightButtonDown +=
                 border_mouseRightButtonDown;
         }
    
     private readonly TranslateTransform _interactiveTranslateTransform;
    

    首先声明了一个私有的只读的TranslateTransform类型的对象_interactiveTranslateTransform,然后在MainWindow的构造函数中赋值。

     _interactiveTranslateTransform = new TranslateTransform();
    

    TranslateTransform是什么?有什么作用呢?

    image-20240401100405500

    它的基本结构:

     //
     // 摘要:
     //     Translates (moves) an object in the 2-D x-y coordinate system.
     public sealed class TranslateTransform : Transform
     {
    
         public static readonly DependencyProperty XProperty;
      
         public static readonly DependencyProperty YProperty;
    
         public TranslateTransform();
       
         public TranslateTransform(double offsetX, double offsetY);
    
         public override Matrix Value { get; }
       
         public double X { get; set; }
      
         public double Y { get; set; }
    
         public TranslateTransform Clone();
     
         public TranslateTransform CloneCurrentValue();
         protected override Freezable CreateInstanceCore();
     }
    

    TranslateTransform 是 WPF 中的一个类,它表示一个 2D 平移变换。这个类是 Transform 类的派生类,用于在 2D 平面上移动(平移)对象。
    TranslateTransform 类有两个主要的属性:X 和 Y,它们分别表示在 X 轴和 Y 轴上的移动距离。例如,如果你设置 X 为 100 和 Y 为 200,那么应用这个变换的元素将会向右移动 100 像素,向下移动 200 像素。

     _interactiveEllipse.RenderTransform =
                 _interactiveTranslateTransform;
    

    _interactiveEllipse元素的RenderTransform属性设置为_interactiveTranslateTransform

    image-20240401101111864

    RenderTransform属性用于获取或设置影响 UIElement 呈现位置的转换信息。

     _containerBorder.MouseLeftButtonDown +=
        border_mouseLeftButtonDown;
     _containerBorder.MouseRightButtonDown +=
         border_mouseRightButtonDown;
    

    这是在注册 _containerBorder的鼠标左键点击事件与鼠标右键点击事件。

    image-20240401101323899

    image-20240401101401446

    注意当Border这样写时,不会触发鼠标点击事件:

     
    

    这是因为在 WPF 中,Border 控件的背景默认是透明的,这意味着它不会接收鼠标事件。当你设置了背景颜色后,Border 控件就会开始接收鼠标事件,因为它现在有了一个可见的背景。
    如果你希望 Border 控件在没有背景颜色的情况下也能接收鼠标事件,你可以将背景设置为透明色。这样,虽然背景看起来是透明的,但它仍然会接收鼠标事件。

    可以这样设置:

    
    

    鼠标点击事件处理程序

    以鼠标左键点击事件处理程序为例,进行说明:

      private void border_mouseLeftButtonDown(object sender, MouseButtonEventArgs e)
      {
          var clickPoint = Mouse.GetPosition(_containerBorder);
    
          // Set the target point so the center of the ellipse
          // ends up at the clicked point.
          var targetPoint = new Point
          {
              X = clickPoint.X - _interactiveEllipse.Width / 2,
              Y = clickPoint.Y - _interactiveEllipse.Height / 2
          };
    
          // Animate to the target point.
          var xAnimation =
              new DoubleAnimation(targetPoint.X,
                  new Duration(TimeSpan.FromSeconds(4)));
          _interactiveTranslateTransform.BeginAnimation(
              TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace);
    
          var yAnimation =
              new DoubleAnimation(targetPoint.Y,
                  new Duration(TimeSpan.FromSeconds(4)));
          _interactiveTranslateTransform.BeginAnimation(
              TranslateTransform.YProperty, yAnimation, HandoffBehavior.SnapshotAndReplace);
    
          // Change the color of the ellipse.
          _interactiveEllipse.Fill = Brushes.Lime;
      }
    

    重点是:

     // Animate to the target point.
          var xAnimation =
              new DoubleAnimation(targetPoint.X,
                  new Duration(TimeSpan.FromSeconds(4)));
          _interactiveTranslateTransform.BeginAnimation(
              TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace);
    
          var yAnimation =
              new DoubleAnimation(targetPoint.Y,
                  new Duration(TimeSpan.FromSeconds(4)));
          _interactiveTranslateTransform.BeginAnimation(
              TranslateTransform.YProperty, yAnimation, HandoffBehavior.SnapshotAndReplace);
    

    DoubleAnimation类的介绍:

    image-20240401102112194

    DoubleAnimation 是 WPF 中的一个类,它用于创建从一个 double 值到另一个 double 值的动画。这个类是 AnimationTimeline 类的派生类,它可以用于任何接受 double 类型的依赖属性。
    DoubleAnimation 类有几个重要的属性:
    • From:动画的起始值。
    • To:动画的结束值。
    • By:动画的增量值,用于从 From 值增加或减少。
    • Duration:动画的持续时间。
    • AutoReverse:一个布尔值,指示动画是否在到达 To 值后反向运行回 From 值。
    • RepeatBehavior:定义动画的重复行为,例如,它可以设置为无限重复或重复特定的次数。

      var xAnimation =
              new DoubleAnimation(targetPoint.X,
                  new Duration(TimeSpan.FromSeconds(4)));
    

    我们使用的是这种形式的重载:

    image-20240401102332146

    设置了一个要达到的double类型值与达到的时间,这里设置为了4秒。

     _interactiveTranslateTransform.BeginAnimation(
              TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace);
    

    image-20240401102753637

    • _interactiveTranslateTransform.BeginAnimation:这是 BeginAnimation 方法的调用,它开始一个动画,该动画会改变一个依赖属性的值。在这个例子中,改变的是 _interactiveTranslateTransform 对象的 X 属性。
    • TranslateTransform.XProperty:这是 TranslateTransform 类的 X 依赖属性。这个属性表示在 X 轴上的移动距离。
    • xAnimation:这是一个 DoubleAnimation 对象,它定义了动画的目标值和持续时间。在这个例子中,动画的目标值是鼠标点击的位置,持续时间是 4 秒。
    • HandoffBehavior.SnapshotAndReplace:这是 HandoffBehavior 枚举的一个值,它定义了当新动画开始时,如何处理正在进行的动画。SnapshotAndReplace 表示新动画将替换旧动画,并从旧动画当前的值开始。

    全部代码

    xaml:

    
        
            
                
            
        
    
    

    cs:

    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace AnimationDemo
    {
        /// 
        /// Interaction logic for MainWindow.xaml
        /// 
        public partial class MainWindow : Window
        {
            private readonly TranslateTransform _interactiveTranslateTransform;
            public MainWindow()
            {
                InitializeComponent();
    
                _interactiveTranslateTransform = new TranslateTransform();
    
                _interactiveEllipse.RenderTransform =
                    _interactiveTranslateTransform;
    
                _containerBorder.MouseLeftButtonDown +=
                   border_mouseLeftButtonDown;
                _containerBorder.MouseRightButtonDown +=
                    border_mouseRightButtonDown;
            }
    
            private void border_mouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                var clickPoint = Mouse.GetPosition(_containerBorder);
    
                // Set the target point so the center of the ellipse
                // ends up at the clicked point.
                var targetPoint = new Point
                {
                    X = clickPoint.X - _interactiveEllipse.Width / 2,
                    Y = clickPoint.Y - _interactiveEllipse.Height / 2
                };
    
                // Animate to the target point.
                var xAnimation =
                    new DoubleAnimation(targetPoint.X,
                        new Duration(TimeSpan.FromSeconds(4)));
                _interactiveTranslateTransform.BeginAnimation(
                    TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace);
    
                var yAnimation =
                    new DoubleAnimation(targetPoint.Y,
                        new Duration(TimeSpan.FromSeconds(4)));
                _interactiveTranslateTransform.BeginAnimation(
                    TranslateTransform.YProperty, yAnimation, HandoffBehavior.SnapshotAndReplace);
    
                // Change the color of the ellipse.
                _interactiveEllipse.Fill = Brushes.Lime;
            }
    
            private void border_mouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                // Find the point where the use clicked.
                var clickPoint = Mouse.GetPosition(_containerBorder);
    
                // Set the target point so the center of the ellipse
                // ends up at the clicked point.
                var targetPoint = new Point
                {
                    X = clickPoint.X - _interactiveEllipse.Width / 2,
                    Y = clickPoint.Y - _interactiveEllipse.Height / 2
                };
    
    
                // Animate to the target point.
                var xAnimation =
                    new DoubleAnimation(targetPoint.X,
                        new Duration(TimeSpan.FromSeconds(4)));
                _interactiveTranslateTransform.BeginAnimation(
                    TranslateTransform.XProperty, xAnimation, HandoffBehavior.Compose);
    
                var yAnimation =
                    new DoubleAnimation(targetPoint.Y,
                        new Duration(TimeSpan.FromSeconds(4)));
                _interactiveTranslateTransform.BeginAnimation(
                    TranslateTransform.YProperty, yAnimation, HandoffBehavior.Compose);
    
                // Change the color of the ellipse.
                _interactiveEllipse.Fill = Brushes.Orange;
            }
        }
    }
    

    实现效果:

    实现效果

    参考

    1、Microsoft Learn:培养开拓职业生涯新机遇的技能

    2、WPF-Samples/Animation/LocalAnimations/InteractiveAnimationExample.cs at main · microsoft/WPF-Samples (github.com)

  • 相关阅读:
    【微服务】微服务学习笔记一:微服务技术栈介绍
    Flask 学习-96.Flask-SQLAlchemy 判断查询结果是否存在的几种方式
    【补题日记】[2022牛客暑期多校2]I-let fat tension
    数据结构与算法-第六章 图的应用 拓扑排序
    使用Jenkins实现前端自动化打包部署(Linux版本)
    API低代码平台介绍4-数据库记录插入功能
    【深度学习】系统架构工具链的学习笔记
    【AI基础】大模型资源整理
    LeetCode刷题---有效的括号
    BaGet搭建Nuget私仓(window10&docker)
  • 原文地址:https://www.cnblogs.com/mingupupu/p/18108029