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
中包含一个圆形。
页面设计的效果如下所示:
一些设置
相关设置的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
是什么?有什么作用呢?
它的基本结构:
//
// 摘要:
// 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
。
RenderTransform
属性用于获取或设置影响 UIElement 呈现位置的转换信息。
_containerBorder.MouseLeftButtonDown +=
border_mouseLeftButtonDown;
_containerBorder.MouseRightButtonDown +=
border_mouseRightButtonDown;
这是在注册 _containerBorder
的鼠标左键点击事件与鼠标右键点击事件。
注意当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
类的介绍:
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)));
我们使用的是这种形式的重载:
设置了一个要达到的double类型值与达到的时间,这里设置为了4秒。
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace);
• _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;
}
}
}
实现效果:
参考
1、Microsoft Learn:培养开拓职业生涯新机遇的技能
WPF中动画教程(DoubleAnimation的基本使用)的更多相关文章
- WPF利用动画实现圆形进度条
原文:WPF利用动画实现圆形进度条 这是我的第一篇随笔,最近因为工作需要,开始学习WPF相关技术,自己想实现以下圆形进度条的效果,逛了园子发现基本都是很久以前的文章,实现方式一般都是GDI实现的,想到 ...
- WPF中的动画——(三)时间线(TimeLine)
WPF中的动画——(三)时间线(TimeLine) 时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下 ...
- WPF异步载入图片,附带载入中动画
原文:WPF异步载入图片,附带载入中动画 WPF异步载入图片,附带载入中动画 最近,在做一个WPF项目.项目中有一个需求,就是以列表的方式显示出项目图片.这些图片有的存在于互联网上,有的存在于本地磁盘 ...
- WPF中的DoubleAnimation
原文:WPF中的DoubleAnimation WPF中的DoubleAnimation ...
- (转载)WPF中的动画——(一)基本概念
http://www.cnblogs.com/TianFang/p/4050845.html WPF的一个特点就是支持动画,我们可以非常容易的实现漂亮大方的界面.首先,我们来复习一下动画的基本概念.计 ...
- WPF中的动画
动画无疑是WPF中最吸引人的特色之一,其可以像Flash一样平滑地播放并与程序逻辑进行很好的交互.这里我们讨论一下故事板. 在WPF中我们采用Storyboard(故事板)的方式来编写动画,为了对St ...
- WPF中的动画——(一)基本概念
WPF的一个特点就是支持动画,我们可以非常容易的实现漂亮大方的界面.首先,我们来复习一下动画的基本概念.计算机中的动画一般是定格动画,也称之为逐帧动画,它通过每帧不同的图像连续播放,从而欺骗眼和脑产生 ...
- 【WPF学习笔记】[转]周银辉之WPF中的动画 && 晓风影天之wpf动画——new PropertyPath属性链
(一)WPF中的动画 动画无疑是WPF中最吸引人的特色之一,其可以像Flash一样平滑地播放并与程序逻辑进行很好的交互.这里我们讨论一下故事板. 在WPF中我们采用Storyboard(故事板)的方式 ...
- WPF中自动增加行(动画)的TextBox
原文:WPF中自动增加行(动画)的TextBox WPF中自动增加行(动画)的TextBox WPF中的Textbox控件是可以自动换行的,只要设置TextWrapping属性为"Wrap& ...
- WPF中的PathAnimation(路径动画)
原文:WPF中的PathAnimation(路径动画) WPF中的PathAnimation(路径动画) ...
随机推荐
- Redis 缓存过期删除/淘汰策略分析
Redis 缓存过期删除/淘汰策略分析 Redis 缓存删除 Redis 键过期删除,定期删除(主动)和惰性删除(被动) Redis 内存不足时,缓存淘汰策略 key 键过期删除 我们用 redis ...
- 【Android逆向】脱壳项目frida_dump 原理分析
脱dex核心文件dump_dex.js 核心函数 function dump_dex() { var libart = Process.findModuleByName("libart.so ...
- linux下安装nginx(编译安装)及反向代理及负载均衡
首先卸载掉之前用yum命令下载的nginx yum remove nginx 安装nginx需要的依赖库 yum install -y gcc patch libffi-devel python-de ...
- 【八股cover#2】CPP语法 Q&A与知识点
CPP语法 Q&A与知识点 简历cover 1.熟练使用C的指针应用及内存管理 指针与引用的区别 指针是一个存储地址的变量,可以有多级,可以为空,并且在初始化后可以改变指向: 引用是原变量的别 ...
- 【Azure 应用服务】遇见“无法创建hybrid connection for App Service”的解决办法
Hybrid Connection (混合连接) 在两个联网应用程序之间启用了双向.请求-响应和二进制流通信以及简单的数据报流.通过混合连接,可以实现应用部署在公网环境中,而数据库保存在本地私网环境中 ...
- 2023 年值得一读的技术文章 | NebulaGraph 技术社区
在之前的产品篇,我们了解到了 NebulaGraph 内核及周边工具在 2023 年经历了什么样的变化.伴随着这些特性的变更和上线,在[文章]博客分类中,一篇篇的博文记录下了这些功能背后的设计思考和研 ...
- Python基础之程序与用户交互
[一]Python基础之程序与用户交互 [一]程序如何与用户交互 用户通过input命令在窗口内与输入就可以让用户和窗口进行交流 input接受的所有数据类型都是 str 类型 username = ...
- Spring事务(二)-@Transactional注解
上一节说了Spring的事务配置,其中,声明式事务配置里有5种配置方式, @Transactional注解应该是最为常用的一种方式了.这一节就说说@Transactional注解. @Transact ...
- 一个简单的spdlog使用示例
目录 引用源码 封装Log头文件 使用方法 spdlog是一个开源.跨平台.无依赖.只有头文件的C++11日志库,网上介绍的文章有很多这里就不过多的介绍了,GitHub链接:https://githu ...
- 玩转Vue3之深入理解响应式编程
前言 Vue 3是一个功能强大的前端框架,它引入了一些令人兴奋的新特性,其中最引人注目的是ref和reactive.这两个API是Vue 3中响应式编程的核心,本文将深入探讨它们的用法和差异. 什么是 ...