动画对于App来讲,很是的重要。不少App,正是由于有了动画,因此才会以为炫酷。移动端的动画库有很是的多,例如iOS上的Pop、web端的animate.css、Android端的AndroidViewAnimations、跨平台的Lottie等。正是由于有了这些封装好的动画库,咱们制做酷炫的效果方便了很多。固然了,这些库都是基于各平台基础的动画API实现的,笔者今天要聊的,也就是基础的动画及背后的原理。css
动画顾名思义,就是动起来的画面。画面为何会动起来了呢?在回答这个问题以前,咱们先引入一个概念。android
人眼在观察景物时,光信号传入大脑神经,需通过一段短暂的时间,光的做用结束后,视觉形象并不当即消失,这种残留的视觉称“后像”,视觉的这一现象则被称为“视觉暂留”。ios
视觉暂留被认为是电影的最重要的一个理论基础。咱们看到的动画,其实是一连串的画面组成,只不过是以很快的速度去播放,人眼在下一个画面出来以前,还残留着上一个画面的视觉,看起来就像是在没有间隔的播放这一系列的图片,也就是咱们称之为的动画。git
动画会有不少相关的概念,理解了这些概念,会对实际的使用更有帮助。github
刚才在介绍动画本质的时候,用到了画面这个词汇,只是方便读者去理解,这个画面,在学术上叫作帧
。web
帧就是影像动画中最小单位的单幅影像画面,一帧就是一副静止的画面。canvas
帧里面又分为关键帧和过渡帧,这两概念是理解一些动画的基础,例如Android中的补间动画。在一些场景中,咱们可能不会给出一个动画的全部帧,因此将帧分红关键帧和过渡帧。关键帧能够理解为一个动画的起始状态,而过渡帧则是系统自动完成插在关键帧之间的部分。框架
咱们知道Android中的补间动画,基础的有四种类型,平移、缩放、旋转、透明度。而咱们设置动画的时候,一般只是设置起始的状态,也就是关键帧,中间过程其实咱们并不须要去考虑,若是关注动画速率的话,顶多加一个差值器去控制,可是中间生成的帧咱们并无提供。函数
系统为何可以补齐过渡帧呢?咱们看下这四种基本的动画类型,给定起始状态,中间状态咱们实际上是能够经过计算推演出来的,这也是系统为何可以补齐的缘由。post
是否是只有这四种才能够经过系统填补过渡帧呢?显然不是的,例如一个跳跃前进的动画,添加一些限制条件,就能够推演出中间的状态。系统提供的只是比较常见的四种,并非说只有这四种,而是绝大部分动画均可以经过这四种组合实现。固然了,确定也是有实现不了的,这个时候有一个办法就是经过canvas画出来。
另外再插一嘴,Android系统提供的四种动画操做,也是变换矩阵是四维的缘由,具体的就很少说了,以前文章也有介绍过。
最后一嘴,此处讲解帧的概念,拿了不少Android相关的知识去讲解,只是但愿读者可以经过一些已知的概念,去理解一些未知的。动画的原理都同样,具体到某个平台,可能顶多就是实现或者叫法不同罢了。
小时候不少人都玩过书角动画。在书或者本子的一角,每一页都画上一个画面,而后拨书角,不一样速度拨,动画的感觉不同,拨的越快,动画越流畅。这是为何呢?这就牵扯到帧数与FPS了。
帧数,帧的数量。FPS(Frame per Second),即每秒显示帧数。
这两个概念,主要是FPS有什么做用呢?这是由于人眼生理构造的缘由。人眼残留镜像的时间是有限的,若是过了这个时间,下一帧尚未变化,就会感受不流畅。但也不是帧数越大越好,毕竟人眼也是有极限的。
若是动画播放一直都是这种匀速的进行,那表现形式就太单一了。那如何实现非线性的动画效果呢,这个时候就须要用到插值器了。
插值器其实并不复杂,就是一个数学函数,设置属性值从初始值过渡到结束值的变化规律。每一个平台都有本身定义好的一系列插值器,能够供开发者选择使用,也提供自定义的接口,本质上是一个贝塞尔函数。
一个匀速插值器以下:
属性值百分比 = 时间百分比
动画的基本原理和一些基本概念都介绍了一下,如今来聊一下动画的实现。
先抛开系统层级的各类渲染优化,也仅仅是以补间动画为例,假设以现有的移动平台基础上,去实现一套简单的动画框架,该如何去实现呢?
以Android的为例,要实现平移、缩放、旋转、透明度这四种基础的补间动画,能够看到,这些都是基于某个属性的动画,平移是基于point、缩放是基于scale、旋转是基于angle、透明度是基于alpha。
结合插值器,提炼出一个通用的动画类,这个类的做用是根据插值器,获得视图某个时间点的属性变化的状态。
既然各个时间点的状态已经有了,剩下来的就是让各个状态渲染出来。底层的机制在此处不去讨论,这个地方就须要一个定时器,定时器的做用是每隔一段时间就把素材渲染到屏幕上。
至此,一个简易的动画框架就出来了。若是对各平台比较了解的话,就知道我说的是视图动画,真正的动画引擎不是这么简单,涉及到的技术也比较复杂,可是大致的思想不会有错,无论是哪一种动画,都是跟时间相关的帧序列,只是实现方式不一样。
这也是笔者为何花这么多篇幅去介绍动画相关的概念,知道一些底层原理后,无论什么平台,怎么去实现,底层的思想确定都差很少,只是实现上的不一样。
Flutter动画,与Android、iOS等平台对比,其实自己并无什么特别之处。基本的原理是同样的,只是提供的种类以及实现的方式不一样罢了。
Android的动画,大的分类有两种:
视图动画又能够分为两类:
这之间的差异是什么呢?它们只有实现上的差异
能够看出Android的动画分类仍是比较明晰的。
iOS好久没弄了,在这里也简单说下,不对的话还请各位指正。
显式动画又能够分为两类:
这些动画类别之间的差异是什么呢?
经过动画这一起,能够看出iOS的分类实际上是比较的模糊的,有一些历史包袱。
css动画大致上有两种:
web中的动画分类简单的多了
经过上面个平台动画粗略的介绍,动画在不一样平台虽然被叫着不一样的名称,本质上其实都差很少的,变来变去都是这几种方式,要么根据属性要么根据关键帧,要么更改绘制层,要么更改控件自己属性。一些游戏引擎,虽然我没有看,可是我以为原理也大体类似。
上面铺垫了这么多,终于到Flutter动画了。Flutter是一门比较新的技术,历史包袱理应说是最小的。
Flutter动画分为两类:
补间动画很好理解,基于物理的动画是这个什么鬼。
基于物理的动画是一种遵循物理学定律的动画形式
举个例子,比方说你滑动一张图片,这个过程不是匀速的,而是起始速度快,而后慢慢的降速,就像一本书在地上往前推同样。它有什么特色呢?
哈哈,最后一点是否是似曾相识,这样作的好处是什么呢?随着人们生活水平的极大提高,移动端硬件这些年也是赶英超美,人们再也不知足于简单的动画,因而就有部分有(xian)识(de)之(dan)士(teng),实现了基于物理学定律的动画。
这种动画iOS或者Android有没有呢,是有的,但不是做为最基础的动画API被提供。为何其余平台没有将这个归入最基本的动画中去呢?
基于物理的动画这么好,那有什么好处呢?更天然,更加符合人们的认知。
前面讲的各平台的动画,从本质上看,基于某个属性也好,帧动画也好,都是从一种状态到另外一种状态,而中间过程是能够推演出来的,因此Flutter提供补间动画。
基于物理的动画,我猜想多是为了实现其余平台上的一些效果,例如弹簧、阻尼效果等等。因此Flutter就提供了这种动画API,毕竟没什么包袱。
Flutter提炼了三种动画模式,与其说提炼出来的,倒不如说统一不能更为合适。
Flutter的实现原理以及这个阶段,注定了作动画是很是麻烦的一件事情。跨平台的技术作动画都麻烦,这个彷佛是通识,为了跨平台而同化的一些东西,到异化部分,就变得蛋疼了,动画正是这种存在。
Flutter作动画复杂体如今哪些地方呢?
关于动画的具体的实现、一些底层的代码逻辑以及如何使用,将会在下一篇文章中作介绍。这篇文章更多的是偏于一些普适性的介绍,关于Flutter动画相关的介绍反而不多。但愿读者可以了解一些动画的原理,以及各个平台动画的大体实现方式,这样能够更好的理解Flutter动画的设计思想。文中如有错误的地方,还恳请指出,在此不胜感激。
笔者建了一个Flutter学习相关的项目,Github地址,里面包含了笔者写的关于Flutter学习相关的一些文章,会按期更新,也会上传一些学习Demo,欢迎你们关注。