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

实现效果

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

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

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

页面设计

xaml如下所示:

<Window x:Class="AnimationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel>
<Border x:Name="_containerBorder" Background="Transparent">
<Ellipse x:Name="_interactiveEllipse"
Fill="Lime"
Stroke="Black"
StrokeThickness="2.0"
Width="25"
Height="25"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Border>
</DockPanel>
</Window>

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

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

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

一些设置

相关设置的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是什么?有什么作用呢?

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

它的基本结构:

 //
 // 摘要:
 //     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 { getset; }
  
     public double Y { getset; }

     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

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

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

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

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

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

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

 <Border x:Name="_containerBorder">

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

可以这样设置:

<Border x:Name="_containerBorder" Background="Transparent">

鼠标点击事件处理程序

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

  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类的介绍:

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

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)));

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

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

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

 _interactiveTranslateTransform.BeginAnimation(
          TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace);
WPF中动画教程(DoubleAnimation的基本使用)

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

全部代码

xaml:

<Window x:Class="AnimationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel>
<Border x:Name="_containerBorder" Background="Transparent">
<Ellipse x:Name="_interactiveEllipse"
Fill="Lime"
Stroke="Black"
StrokeThickness="2.0"
Width="25"
Height="25"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Border>
</DockPanel>
</Window>

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
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    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;
        }
    }
}

实现效果:

WPF中动画教程(DoubleAnimation的基本使用)
实现效果

参考

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

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


原文始发于微信公众号(DotNet学习交流):WPF中动画教程(DoubleAnimation的基本使用)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/264684.html

(0)
java小白的头像java小白

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!