前言

缓动在动画效果中应用非常广泛,在合适的时候使用一些缓动效果会使得效果更加符合人的直观感受,简单来说,会显得更加自然。

WPF提供了11种缓动效果,涵盖了大部分的使用场景。不过如果需要在非WPF下使用这些缓动效果,就需要知道对应的曲线公式了。因为公式是通用的,所以可以很轻松的使用其他语言实现。

由于本人数学水平有限,所以本文注重的应用而不是原理。在本文中,将会使用C#去实现,并附上与WPF原版的对比效果。

本文参考:

1,https://docs.microsoft.com/zh-cn/dotnet/desktop/wpf/graphics-multimedia/easing-functions?view=netframeworkdesktop-4.8

2,https://github.com/ai/easings.net

文末会附上示例源代码,需要者可自行下载。

本文地址:https://www.cnblogs.com/lesliexin/p/13594811.html


一、WPF中的缓动效果

在WPF中,共有11种:Back,Bounce,Circle,Quadratic,Cubic,Quartic,Quintic,Elastic,Exponential,Sine,Power。不过严格来说只有7种,因为Quadratic,Cubic,Quartic,Quintic是由Power去实现的,由于Power参数未定,所以仅实现前10种效果。

所以对于每个缓动效果而言,都有三种模式:缓入(EaseIn)、缓出(EaseOut)、缓入缓出(EaseInOut)。


二、公式与动画

一个元素的动画效果,其实就是这个元素变化的快慢,也就是速度。速度与时间间隔和该时间间隔内运动距离两个变量有关。在实际实现中,时间间隔是相等的,那么速度的变化与距离的变化就成正比。在一个二维坐标当中,横坐标为时间,纵坐标为距离,那么其形成的曲线中,曲线越陡,速度越快,曲线越平缓,则速度越慢。

而我们使用公式的目的,就是取得这个纵坐标的值。

不过,要注意的是,我们获取的曲线的时间范围是:0~1,这不是具体的1秒或1毫秒,而是“单位1”。举例来说,如果一个动画效果时长是2000ms,那么在第x ms时,对应的单位时间就是x/2000。


三、缓动公式、缓动效果、与WPF对比

1,Back

曲线(图源自MSDN):

1.1,曲线公式

public static double Back(double x, LEaseMode easeMode)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return 2.70158 * x * x * x - 1.70158 * x * x;
case LEaseMode.EaseOut:
return 1 + 2.70158 * Math.Pow(x - 1, 3) + 1.70158 * Math.Pow(x - 1, 2);
case LEaseMode.EaseInOut:
return x < 0.5 ? (Math.Pow(2 * x, 2) * (7.189819 * x - 2.5949095)) / 2 : (Math.Pow(2 * x - 2, 2) * (7.189819 * x - 4.5949095) + 2) / 2;
default:
return 0;
}
}

Back

1.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

1.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

2,Bounce

曲线(图源自MSDN):

2.1,曲线公式

private static double BounceOut(double x)
{
if (x < 1d / 2.75d) return 7.5625 * x * x;
else if (x < 2d / 2.75d) return 7.5625 * (x -= 1.5d / 2.75d) * x + 0.75;
else if(x<2.5d/2.75d) return 7.5625 * (x -= 2.25d / 2.75d) * x + 0.9375;
else return 7.5625 * (x -= 2.625d / 2.75d) * x + 0.984375;
} public static double Bounce(double x, LEaseMode easeMode)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return 1 - BounceOut(1 - x);
case LEaseMode.EaseOut:
return BounceOut(x);
case LEaseMode.EaseInOut:
return x < 0.5 ? (1 - BounceOut(1 - 2 * x)) / 2 : (1 + BounceOut(2 * x - 1)) / 2;
default:
return 0;
}
}

Bounce

2.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

2.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

3,Circle

曲线(图源自MSDN):

3.1,曲线公式

public static double Circle(double x, LEaseMode easeMode)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return 1 - Math.Sqrt(1 - Math.Pow(x, 2));
case LEaseMode.EaseOut:
return Math.Sqrt(1 - Math.Pow(x - 1, 2));
case LEaseMode.EaseInOut:
return x < 0.5 ? (1 - Math.Sqrt(1 - Math.Pow(2 * x, 2))) / 2 : (Math.Sqrt(1 - Math.Pow(-2 * x + 2, 2)) + 1) / 2;
default:
return 0;
}
}

Circle

3.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

3.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

4,Quadratic

曲线(图源自MSDN):

4.1,曲线公式

public static double Power(double x,LEaseMode easeMode,int power)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return Math.Pow(x, power);
case LEaseMode.EaseOut:
return 1-Math.Pow(1-x,power);
case LEaseMode.EaseInOut:
return x < 0.5 ? Math.Pow(2,power-1)*Math.Pow(x,power) : 1 - Math.Pow(-2 * x + 2, power) / 2;
default:
return 0;
}
} public static double Quadratic(double x, LEaseMode easeMode)
{
return Power(x, easeMode, 2);
}

Quadratic

4.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

4.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

5,Cubic

曲线(图源自MSDN):

5.1,曲线公式

public static double Power(double x,LEaseMode easeMode,int power)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return Math.Pow(x, power);
case LEaseMode.EaseOut:
return 1-Math.Pow(1-x,power);
case LEaseMode.EaseInOut:
return x < 0.5 ? Math.Pow(2,power-1)*Math.Pow(x,power) : 1 - Math.Pow(-2 * x + 2, power) / 2;
default:
return 0;
}
} public static double Cubic(double x, LEaseMode easeMode)
{
return Power(x, easeMode, 3);
}

Cubic

5.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

5.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

6,Quartic

曲线(图源自MSDN):

6.1,曲线公式

public static double Power(double x,LEaseMode easeMode,int power)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return Math.Pow(x, power);
case LEaseMode.EaseOut:
return 1-Math.Pow(1-x,power);
case LEaseMode.EaseInOut:
return x < 0.5 ? Math.Pow(2,power-1)*Math.Pow(x,power) : 1 - Math.Pow(-2 * x + 2, power) / 2;
default:
return 0;
}
} public static double Quartic(double x, LEaseMode easeMode)
{
return Power(x, easeMode,4);
}

Quartic

6.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

6.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

7,Quintic

曲线(图源自MSDN):

7.1,曲线公式

public static double Power(double x,LEaseMode easeMode,int power)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return Math.Pow(x, power);
case LEaseMode.EaseOut:
return 1-Math.Pow(1-x,power);
case LEaseMode.EaseInOut:
return x < 0.5 ? Math.Pow(2,power-1)*Math.Pow(x,power) : 1 - Math.Pow(-2 * x + 2, power) / 2;
default:
return 0;
}
} public static double Quintic(double x, LEaseMode easeMode)
{
return Power(x, easeMode, 5);
}

Quintic

7.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

7.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

8,Elastic

曲线(图源自MSDN):

8.1,曲线公式

public static double Elastic(double x, LEaseMode easeMode)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return x == 0 ? 0 : x == 1 ? 1 : -Math.Pow(2, 10 * x - 10) * Math.Sin((x * 10 - 10.75) * 2 * Math.PI / 3);
case LEaseMode.EaseOut:
return x == 0 ? 0 : x == 1 ? 1 : Math.Pow(2, -10 * x) * Math.Sin((x * 10 - 0.75) * 2 * Math.PI / 3)+1;
case LEaseMode.EaseInOut:
return x == 0 ? 0 : x == 1 ? 1 : x < 0.5 ? -(Math.Pow(2, 20 * x - 10) * Math.Sin((x * 20 - 11.125) * 2 * Math.PI / 4.5)) / 2 : (Math.Pow(2, -20 * x + 10) * Math.Sin((x * 20 - 11.125) * 2 * Math.PI / 4.5)) / 2 + 1;
default:
return 0;
}
}

Elastic

8.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

8.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

9,Exponential

曲线(图源自MSDN):

9.1,曲线公式

public static double Exponential(double x, LEaseMode easeMode)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return x == 0 ? 0 : Math.Pow(2, 10 * x - 10);
case LEaseMode.EaseOut:
return x == 1 ? 1 : 1 - Math.Pow(2, -10 * x);
case LEaseMode.EaseInOut:
return x == 0 ? 0 : x == 1 ? 1 : x < 0.5 ? Math.Pow(2, 20 * x - 10) / 2 : (2 - Math.Pow(2, -20 * x + 10)) / 2;
default:
return 0;
}
}

Exponential

9.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

9.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:

10,Sine

曲线(图源自MSDN):

10.1,曲线公式

public static double Sine(double x, LEaseMode easeMode)
{
switch (easeMode)
{
case LEaseMode.EaseIn:
return 1 - Math.Cos((x * Math.PI) / 2);
case LEaseMode.EaseOut:
return Math.Sin((x * Math.PI) / 2);
case LEaseMode.EaseInOut:
return -(Math.Cos(Math.PI * x) - 1) / 2;
default:
return 0;
}
}

Sine

10.2,WinForm效果

a,EaseIn:

b,EaseOut:

c,EaseInOut:

10.3,WPF效果

(上面矩形为WPF原版缓动效果,下面矩形为公式实现效果)

a,EaseIn:

b,EaseOut:

c,EaseInOut:


四、结束语

通过上面的动图我们会发现,其中一些效果,使用公式生成的与WPF原版的是不一样的,一是因为WPF原版的曲线不是固定的,还有其他参数去调控,而我对比的时候使用的是WPF默认的缓动效果;二是因为一像Bounce、Elastic等曲线以我的能力很难扒出来具体的公式,所以更多的是依照文首的Github上那个项目中的公式。所以难免有所差异。

同时,写本篇文章是因为在之后的自定义控件系列文章,以及其他涉及图形的文章中,会频繁的使用缓动效果以增强直观感受,到时文章中会引用本文所生成的类库,当然也会随文附上缓动公式。


五、源代码下载

源代码包含:

1,缓动类库

2,WinForm演示

3,WPF演示

https://files.cnblogs.com/files/lesliexin/LEase.7z

缓动公式整理(附:C#实现及WPF原版对比)的更多相关文章

  1. css3 缓动公式

    var easingMap = { "linear": [0.250, 0.250, 0.750, 0.750], "ease": [0.250, 0.100, ...

  2. javascript的缓动效果

    这部分对原先的缓动函数进行抽象化,并结合缓动公式进行强化.成品的效果非常惊人逆天.走过路过不要错过. 好了,打诨到此为止.普通的加速减速是难以让人满意的,为了实现弹簧等让人眼花缭乱的效果必须动用缓动公 ...

  3. 缓动动画(json)

    function animate(obj, json){ clearInterval(obj.timer); obj.timer=setInterval(function(){ var flag = ...

  4. javascript 45种缓动效果BY司徒正美

    javascript 45种缓动效果 参数 类型 说明 el element 必需,为页面元素 begin number 必需,开始的位置 change number 必需,要移动的距离 durati ...

  5. jQuery-1.9.1源码分析系列(十五) 动画处理——缓动动画核心Tween

    在jQuery内部函数Animation中调用到了createTweens()来创建缓动动画组,创建完成后的结果为: 可以看到上面的缓动动画组有四个原子动画组成.每一个原子动画的信息都包含在里面了. ...

  6. 利用tween.js算法生成缓动效果

    在讲tween类之前,不得不提的是贝塞尔曲线了.首先,贝塞尔曲线是指依据四个位置任意的点坐标绘制出的一条光滑曲线.它在作图工具或动画中中运用得比较多,例如PS中的钢笔工具,firework中的画笔等等 ...

  7. Silverlight动画学习笔记(三):缓动函数

    (一)定义: 缓动函数:可以将自定义算术公式应用于动画 (二)为什么要用缓动函数: 您可能希望某一对象逼真地弹回或其行为像弹簧一样.您可以使用关键帧动画甚至 From/To/By 动画来大致模拟这些效 ...

  8. JS基础知识——缓动动画

    基于距离的缓动动画 原理:设定起始位置  start 和终止位置 end,变化会越来越慢. 公式:start=start+(end-start)/10;     这个10不是固定的,想分成多少份就分成 ...

  9. JS实现缓动动画效果

    原理如下: 假设要从数值A变化到数值B,如果是线性运动,则每次移动距离是一样:如果是缓动,每次移动距离不一样.那如何才能不一样呢?很简单,按比例移动就可以. 例如:每次移动剩余距离的一半. 对吧,超容 ...

随机推荐

  1. java基础-04:标识符与关键字

    在Java中,标识符是代表你对程序中某个方法或变量赋予的一个名称,而这个名称不能是关键字 关键字:

  2. idea 推送jar包到maven私库

    1.推送到本地仓库 idea直接install即可 2.推送到公司私库 2.1 使用配置公司仓库地址的setting文件 <?xml version="1.0" encodi ...

  3. 计算机网络-传输层(3)TCP协议与拥堵控制

    TCP是因特网传输层的面向连接的可靠的运输协议.   TCP被称为是面向连接的:通信双方在发送数据之前必须建立连接,连接状态只在连接的两端中维护,在沿途节点中并不维护状态. TCP连接包括:两台主机上 ...

  4. 区块链入门到实战(33)之Solidity – 数据类型

    在用任何语言编写程序时,都需要使用变量来存储各种信息.变量是内存空间的名称,变量有不同类型,例如整型.字符串类型等等.操作系统根据变量的数据类型分配内存. Solidity中,变量类型有以下几大类: ...

  5. 从原理上理解MySQL的优化建议

    从原理上理解MySQL的优化建议 预备知识 B+树索引 mysql的默认存储引擎InnoDB使用B+树来存储数据的,所以在分析优化建议之前,了解一下B+树索引的基本原理. 上图是一个B+树索引示意图, ...

  6. Pycharm2019.3永久激活

    1. 下载破解补丁,https://pan.baidu.com/s/1mcQM8CLUnweY02ahKEr4PQ ,下载最新上传的压缩包 2. 将压缩包解压,里面有激活文件ACTIVATION_CO ...

  7. 23种设计模式 - 接口隔离(Facade - Proxy - Mediator - Adapter)

    其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 接口隔离 在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接( ...

  8. wmz的数数(数状数组)

    wmz的数数(数状数组) 题目描述 \(wmz\)从小就显现出了过人的天赋,他出生的第三天就证明了哥德巴赫猜想,第五天就证明了质能方程,出生一星期之后,他觉得\(P\)是否等于\(NP\)这个问题比前 ...

  9. 【经验分享】用adb揪出安卓APP弹窗广告的原形

    背景 相信不少安卓用户中过影子弹窗广告的困扰,这种推广APP本体在后台运行,而且可以在其他APP上弹出覆盖广告,一不小心就会误操作,点击广告或者下载APP,着实令人恶心. 以前的广告软件只在通知栏会推 ...

  10. Ubuntu 20.04 手动安装 sublime_text 并建立搜索栏图标(解决 Ubuntu 20.04 桌面图标无法双击打开问题)

    下载sublime_text_3离线程序包 wget https://download.sublimetext.com/sublime_text_3_build_3211_x64.tar.bz2 #x ...