一个简单好用的 C# Easing Animation 缓动动画类库

news2024/9/17 8:29:46

文章目录

  • 1.类库说明
  • 2.使用步骤
    • 2.1 创建一个Windows Form 项目
    • 2.2 安装类库
    • 2.3 编码
    • 2.4 效果
  • 3. 扩展方法
    • 3.1 MoveTo 动画
    • 3.2 使用回调函数的Color动画
    • 3.3 属性动画
    • 3.4 自定义缓动函数
  • 4.该库支持的内置缓动函数
  • 5.代码下载

1.类库说明

App.Animations 类库是一个很精炼、好用的 csharp easing 动画库

  • 基于 net-standard 2.0
  • 提供 Fluent API,写代码非常舒服。
  • 支持多个参数同时参与动画。
  • 自带 30+ 缓动动画效果。
  • 支持自定义缓动动画。
  • 支持无限循环。
  • 支持自动返回。
  • 支持扩展方法,简化动画创建
  • 代码非常精炼,是学习线程控制的好示例项目。

2.使用步骤

2.1 创建一个Windows Form 项目

App.Animations 类库是基于 net-standard 2.0开发的,不依赖于其它任何类库,是可以跨平台使用的。这里以windows form项目为例,演示ui动画。窗口创建好后,在界面上拖入控件,效果如下:

在这里插入图片描述

2.2 安装类库

nuget-install App.Animations

2.3 编码

using App.Animations;
using App.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AnimationForm
{
    public partial class Form1 : Form
    {
        Animator _ani;

        public Form1()
        {
            InitializeComponent();
            BindEnum(this.cmbType1, typeof(AnimationType));
            BindEnum(this.cmbType2, typeof(AnimationType));
        }

        //-------------------------------------------------------
        // Combobox <-> Enum
        //-------------------------------------------------------
        void BindEnum(ComboBox cmb, Type enumType)
        {
            var infos = enumType.GetEnumInfos();
            cmb.Items.Clear();
            foreach (var info in infos)
            {
                cmb.Items.Add(info);
            }
            cmb.SelectedIndex = 0;
        }

        T GetEnum<T>(ComboBox cmb) where T : Enum
        {
            return (T)(cmb.SelectedItem as EnumInfo).Value;
        }

        //-------------------------------------------------------
        // Run
        //-------------------------------------------------------
        private void btnStop_Click(object sender, EventArgs e)
        {
            if (_ani != null)
                _ani.Stop();
        }

        // Animation on x
        private void btnAnimX_Click(object sender, EventArgs e)
        {
            var start = 100;  // x
            var end   = 300;
            var type1 = GetEnum<AnimationType>(cmbType1);
            var type2 = GetEnum<AnimationType>(cmbType2);
            var dur1 = (long)numDur1.Value;
            var dur2 = (long)numDur2.Value;
            _ani = new Animator()
                .SetInterval((int)numInterval.Value)
                .AddPath(type1, start, end, dur1)
                .AddPath(type2, end, start, dur2)
                .SetFrameEvent((values) =>
                {
                    Action action = () => {
                        label1.Left = (int)values[0];
                        label1.Text = string.Format("{0:000}", values[0]);
                    };
                    this.Invoke(action);
                })
                .SetEndEvent((_) => Trace.WriteLine("Animation end."))
                .Start()
                ;
        }


        // Animation on y
        private void btnAnimXY_Click(object sender, EventArgs e)
        {
            var start = new List<double> { 100, 10 };  // x, y
            var end   = new List<double> { 300, 100 };
            var type1 = GetEnum<AnimationType>(cmbType1);
            var type2 = GetEnum<AnimationType>(cmbType2);
            var dur1 = (long)numDur1.Value;
            var dur2 = (long)numDur2.Value;
            _ani = new Animator()
                .SetInterval((int)numInterval.Value)
                .AddPath(type1, start, end, dur1)
                .AddPath(type2, end, start, dur2)
                .SetFrameEvent((values) =>
                {
                    Action action = () => {
                        label1.Left = (int)values[0];
                        label1.Top = (int)values[1];
                        label1.Text = string.Format("({0:000},{1:000})", values[0], values[1]);
                    };
                    this.Invoke(action);
                })
                .SetEndEvent((values) => Trace.WriteLine("Animaion end."))
                .Start();
        }

        // Animation on color
        private void btnAnimColor_Click(object sender, EventArgs e)
        {
            var start = new List<double> { 255, 0, 0 };        // r, g, b
            var end   = new List<double> { 0, 255, 255 };
            var type1 = GetEnum<AnimationType>(cmbType1);
            var type2 = GetEnum<AnimationType>(cmbType2);
            var dur1 = (long)numDur1.Value;
            var dur2 = (long)numDur2.Value;
            _ani = new Animator()
                .SetInterval((int)numInterval.Value)
                .AddPath(type1, start, end, dur1)
                .AddPath(type2, end, start, dur2)
                .SetFrameEvent((values) =>
                {
                    Action action = () => {
                        label1.ForeColor = Color.FromArgb((int)values[0], (int)values[1], (int)values[2]);
                        label1.Text = string.Format("({0:0},{1:0},{2:0})", values[0], values[1], values[2]);
                    };
                    this.Invoke(action);
                })
                .SetEndEvent((values)=>
                {
                    Action action = () => {
                        label1.ForeColor = Color.FromArgb((int)values[0], (int)values[1], (int)values[2]);
                        label1.Text = string.Format("({0:0},{1:0},{2:0})", values[0], values[1], values[2]);
                    };
                    this.Invoke(action);
                })
                .Start()
                ;
        }
    }
}

2.4 效果

在这里插入图片描述

3. 扩展方法

3.1 MoveTo 动画

this.block.MoveTo(new Point(70, 100), new Point(150, 50), 1000, EasingType.Linear); // use moveto extension function to apply animation.

3.2 使用回调函数的Color动画

var startColor = new List { 255, 0, 0 };
var endColor = new List { 0, 255, 255 };
this.block.Animate(startColor, endColor, 1000, (t, vs) => t.BackColor = ToColor(vs)); // use callback to modify property.

3.3 属性动画

this.picBall.Animate(500, -50, 1000, t => t.Left);

3.4 自定义缓动函数

Func<double, double> func = (v) => Math.Sin(vMath.PI2); // define a sin easing function
anim1 = this.picBall.Animate(600, -50, 5000, (t,v) => t.Left = (int)v, EasingType.Linear, infinity:true); // X linear animation
anim2 = this.picBall.Animate(100, 200, 5000, (t,v) => t.Top = (int)v, easingFunc: func, infinity: true); // Y custom animation
在这里插入图片描述

4.该库支持的内置缓动函数

名称说明
Linear线性
BackEaseIn拉后 ease in
BackEaseOut拉后 ease out
BackEaseInOut拉后 ease in and ease out
BounceEaseIn弹性 ease in
BounceEaseOut弹性 ease out
BounceEaseInOut弹性 ease in and ease out
ElasticEaseIn橡皮筋 ease in
ElasticEaseOut橡皮筋 ease out
ElasticEaseInOut橡皮筋 ease in and ease out
QuadraticEaseIn平方 ease in
QuadraticEaseOut平方 ease out
QuadraticEaseInOut平方 ease in and ease out
CubicEaseIn立方 ease in
CubicEaseInOut立方 ease in and cubic ease out
CubicEaseOut立方 ease out
QuarticEaseIn四次方 ease in
QuarticEaseOut四次方 ease out
QuarticEaseInOut四次方 ease in and ease outut
QuinticEaseIn五次方 ease in
QuinticEaseOut五次方 ease out
QuinticEaseInOut五次方 ease in and ease out
ExponentialEaseIn指数 ease in
ExponentialEaseOut指数 ease out
ExponentialEaseInOut指数 ease in and ease out
SinusoidalEaseIn正弦曲线 ease in
SinusoidalEaseOut正弦曲线 ease out
SinusoidalEaseInOut正弦曲线 ease in and ease out
CircularEaseIn圆形 ease in
CircularEaseOut圆形 ease out
CircularEaseInOut圆形 ease in and ease out

5.代码下载

CSDN下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1809001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RT-DETR 详解之查询去噪( DeNoise)

引言 前面我们已经讲解了RT-DETR的基本结构与Efficient Hybrid Encoder部分&#xff0c;在这篇博客里&#xff0c;博主将主要记录RT-DETR的第二个创新点&#xff1a;Uncertainty-minimal Query Selection 查询向量选择为什么重要&#xff1f; 关于 Query Selection&#xff0…

使用WGCLOUD监测进程的cpu和内存使用情况

WGCLOUD是一款国产免费的运维平台&#xff0c;可以监测很多指标数据&#xff0c;我们在这篇文章主要描述如何使用WGCLOUD监测进程 其实官网的进程使用描述也比较清楚&#xff0c;看看 进程应用、中间件监测使用说明&#xff08;对我们关注的业务系统、中间件、进程进行实时监测…

计网总结☞网络层

.................................................. 思维导图 ........................................................... 【Wan口和Lan口】 WAN口&#xff08;Wide Area Network port&#xff09;&#xff1a; 1)用于连接外部网络&#xff0c;如互联…

[chisel]马上要火的硬件语言,快来了解一下优缺点

Chisel是什么&#xff1f; Chisel的全称为Constructing Hardware In a Scala Embedded Language&#xff0c;是一个基于Scala的DSL&#xff08;Domain Specific Language&#xff0c;特定领域专用语言&#xff09;。2012年&#xff0c;加州大学伯克利分校&#xff08;UC Berkel…

大话设计模式解读02-策略模式

本篇文章&#xff0c;来解读《大话设计模式》的第2章——策略模式。并通过Qt和C代码实现实例代码的功能。 1 策略模式 策略模式作为一种软件设计模式&#xff0c;指对象有某个行为&#xff0c;但是在不同的场景中&#xff0c;该行为有不同的实现算法。 策略模式的特点&#…

Mysql的底层实现逻辑

Mysql5.x和Mysql8性能的差异 整体性能有所提高&#xff0c; 在非高并发场景下&#xff0c;他们2这使用区别不大&#xff0c;性能没有明显的区别。 只有高并发时&#xff0c;mysql8才体现他的优势。 2. Mysql数据存储结构Innodb逻辑结构 数据选用B树结构存储数据&#xff0…

IDEA去除代码和XML中的波浪线(黄色警告线)

通常情况下&#xff0c;IDE自带的侦测功能会帮我们提示一些错误、警告等。但这对于强迫症患者来说并不友好。以下是去除IDE代码和XML文件中的波浪线&#xff08;黄色警告线&#xff09;、拯救强迫症患者的有效方案 1、去除XML中的波浪线 2、去除代码中的波浪线 关爱强迫症患者…

QT 信号和槽 通过自定义信号和槽沟通 如何自定义槽和信号的业务,让它们自动关联 自定义信号功能

通过信号和槽机制通信&#xff0c;通信的源头和接收端之间是松耦合的&#xff1a; 源头只需要顾自己发信号就行&#xff0c;不用管谁会接收信号&#xff1b;接收端只需要关联自己感兴趣的信号&#xff0c;其他的信号都不管&#xff1b;只要源头发了信号&#xff0c;关联该信号…

C语言学习系列:GCC编译器Windows版本MinGW-w64的安装教程

本文图文分享如何安装C语言编译器——MinGW-w64。 只要看到这篇文章&#xff0c;就可以按照文中步骤正确安装MinGW-w64并使用。 一、什么是 MinGW-w64 &#xff1f; 我们知道C语言是高级语言&#xff0c;必须编译为二进制文件&#xff0c;才能为计算机运行&#xff0c;MinGW…

每日两题7

文章目录 买卖股票的最佳时机含冷冻期买卖股票的最佳时机含手续费 买卖股票的最佳时机含冷冻期 分析&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();vector<vector<int>> dp(n, vector<int>(3…

path[1][0] path[1][1:-1] [path[1][-1] 分别怎么取的

假设的输入数据 假设 path 变量如下&#xff1a; path [path, [10515194, _derivationally_related_form, 00265386, _derivationally_related_form, 00800940, _hypernym, 00798245, _derivationally_related_form, 02589576]]示例代码 为了更清楚地展示这些操作&#xff…

OSFP 1类LSA详解

概述 上图为1类LSA的实际报文结构 , 在开始之前一定需要说明 , 1类LSA是OSPF中最复杂的LSA类型 , 在LSA头部的文章中详细介绍了 LS Type / Link State ID / Adv Router 3种头部字段 , 在1类LSA的主体内容中还存在类似的字段十分的相似 , 很多网络从业者难以理解的点就在于此 , …

2- 简易版-日记写作软件(java)-涉及的技术点简述

环境&#xff1a; Ubuntu LinuxJDK1.8Eclipse 项目文件结构&#xff1a; 0. 涉及的技术点 1)view 包&#xff08;GUI&#xff09;&#xff1a; Eclipse SwingEclipse WindowBuilderJFileChooser(用于弹出文件选择对话框&#xff0c;进行文件或目录的选择)FileNameExtension…

文案策划背后的秘密 | 职场高手养成记

要想在文案策划这个行当里混&#xff0c;首先得对自己的文字功底有足够的信心&#xff0c;那种“文章独步天下”的气势不可或缺。 要是没有这份自信&#xff0c;我建议你还是另寻他路。 要想跨入文案策划的大门&#xff0c;可以从以下几个方面入手&#xff1a; 1. 学习文案基…

探索OrangePi AIpro:单板计算机的深度体验之旅

准备阶段&#xff1a;环境与资料 在开始我们的探索之旅前&#xff0c;确保您已准备好以下装备&#xff1a; OrangePi AIpro&#xff1a;我们的主角&#xff0c;一台功能强大的单板计算机。Windows 10笔记本电脑&#xff1a;作为我们的辅助工具&#xff0c;用于管理和测试。路…

NOS II - Timer定时器

NOS II-Time定时器 简单回忆NIOS II中定时器的使用。 一、定时器的框图 二、定时器寄存器的描述 定时器的寄存器都是16bit的&#xff0c; 偏移量寄存器名称R/W15bit…4bit3bit2bit1bit0bit0Status - 状态寄存器R/W - 可读可写*****runTO1Control - 控制寄存器R/W***stopsta…

VSFT匿名用户访问-设置

1、先备份配置档 cp -av /etc/vsftpd/vsftpd.conf{,_bak} 2、编辑配置档&#xff0c;修改以下参数 vim /etc/vsftpd/ vsftpd.conf anonymous_enableYES -----允许匿名用户访问 anon_upload_enableYES -----允许匿名用户上传 anon_mkdir_write_enableYES …

汇编语言作业(五)

目录 一、实验目的 二、实验内容 三、实验步骤以及结果 四、实验结果与分析 五、 实验总结 一、实验目的 1.熟悉掌握汇编语言的程序结构&#xff0c;能正确书写数据段、代码段等 2&#xff0c;利用debug功能&#xff0c;查看寄存器&#xff08;CS,IP,AX,DS..)及数据段的…

办公风云颜值背后的职场正能量

办公风云&#xff1a;颜值背后的职场正能量当我们提到职场&#xff0c;脑海中浮现的往往是严肃的面孔、忙碌的身影和堆积如山的文件。但在这个看似单调的舞台上&#xff0c;总有一些人&#xff0c;用他们的颜值和才华&#xff0c;为我们上演了一场场别开生面的“大戏”。今天&a…

【CS.OS】堆管理算法:不同的堆分配和管理算法

1000.5.CS.OS.1.3-基础-内存管理-堆管理算法-Created: 2024-06-09.Sunday10:41 文章目录 1 内存分配算法概述1.1 首次适应&#xff08;First-Fit&#xff09;1.2 最佳适应&#xff08;Best-Fit&#xff09; 2 伙伴系统&#xff08;Buddy System&#xff09; 3 总结References …