Animation=动画,动画是什么呢?下面让我们先来了解下动画的含义
动画是指由许多帧静止的画面,以一定的速度(如每秒16张)连续播放时,肉眼因视觉残象产生错觉,而误以为画面活动的作品。为了得到活动的画面,每个画面之间都会有细微的改变。而画面的制作方式,最常见的是手绘在纸张或赛璐珞片上,其它的方式还包含了运用黏土、模型、纸偶、沙画等。由于电脑科技的进步,现在也有许多利用电脑动画软件,直接在电脑上制作出来的动画,或者是在动画制作过程中使用电脑进行加工的方式,这些都已经大量运用在商业动画的制作中。通常动画是由大量密集和乏味的劳动产生,就算在电脑动画科技得到长足进步和发展的现在也是如此。(From WIKI)
研究表明: 将频率保持在每秒24帧,People就会将这些帧视为一张运动的图像。
下面我将以原生JS以及新颖的CSS3技术来讲解
首先我们先知道一个动画的组成部分。大家都清楚吗?
- delay 时间间隔
- duration 总时间
- start 开始时间(开始状态) -- 不断判断当前时间减去开始时间,只要等于总时间,即运动结束。很Important!
- timePassed 当前时间减去开始时间的值,俗称时间消耗值,好比游戏人物的扣血量,当扣血量=总血量,即死亡!
- progress 把timePassed对比duration转换为当前状态对比末状态的值(这个我解释的比较拗口,还是看下面的例子)
- delta(progress) 根据progress的值,得到该过程(该状态)的相关属性值
- step(delta) 把属性值赋给相应属性,这样我们才能看到每一帧的不同,从而组成一系列不同的状态->"动画"
其次我们得写好Animation的基本框架,这个我老是忘,需要时常回顾才能记得
function animate(opts) { /*opts为一个Json对象,其中包含该动画的组成部分*/
var start = new Date(); /*开始时间,new Date()得到一个时间戳*/
var timer = setInterval(function () {
var timePassed = new Date() - start;
var progress = timePassed / opts.duration;
if (progress>1) { /*由于timePassed不一定会完全等于duration,这个看过js视频的都懂吧,所以这个属于临界值判断*/
progress = 1;
}
var delta = opts.delta(progress); /*得到动画在当前状态应该为的属性值*/
opts.step(delta); /*赋给当前状态的属性*/
if (progress === 1) {
clearInterval(timer);
}
}, opts.delay || 10); /*或位操作符表明delay我们可以不输入*/
}
下面来两幅图给大家加深加深印象。
看到这里,是不是有人想说,我擦,这TM不是物理嘛。嗯··没错,这应该就是高一的运动,从图我们可知,上图为匀速运动,下图为变速(加速)运动。这TM你到底想给我们展示什么啊,别急,嘻嘻,从图我们可以知道Y轴的height是受X轴progress的值绝对的(这里的相关知识,我就不解释了,想了解的请翻回高中物理书籍),而且height值受progress值影响是有蓝色那条线决定的,so,下面我将带给大家有关蓝线的相关知识,前方数学知识颇多,厌者慎入。
咱们先来个霸气的标题,Math,the function of progress delta
大家都知道有哪些函数图形吗?直线?抛物线?曲线?,下面我们一起来回顾下吧,惯例,上图!
由于本人数学功底一般,那么我就直接上函数了,大家准备好了吗?Ready ...
First: 线性函数(linear)
/* 数学上,这函数应该是最基础的了不就是 "y=kx" 嘛,k决定斜率,哈哈,但是在JS中我们应该怎么写,下面代码来了 */
function linear(progress) {
return progress; /* 此时斜率为1,加入想让斜率为k,那么就return k*progress */
}
Second: 幂函数 Power of n
/* 幂函数稍有难度哦 "y=x^n" */
function quad(progress) {
return Math.pow(progress, n);
/* 不知道大家看到这里知道原理了吗?知道就好,Yeah,那么下面我就直接贴代码了哦*/
}
Third
function circ(progress) {
return 1 - Math.sin(Math.acos(progress));
}
Fourth
function back(progress, x) {
/* 这个函数我们引入了新知识点:弹性系数 ,就比如篮球,你把它从高空扔下,
它不会直接下落到地面就静止,它会反弹,直到静止*/
return Math.pow(progress, 2)*((x+1)*progress-x);
}
Fifth
/* 上面既然提到了弹性运动,那么就不得不提下碰撞运动,直接看代码*/
function bounce(progress) {
for (var a=0,b=1,result;1;a+=b,b/=2) {
if (progress >= (7-4*a)/11) {
return -Math.pow((11-6*a-11*progress)/4,2)+Math.pow(b,2);
}
}
}
Sixth
/* 按照上图,除去Fifth,所在图表示 */
function elastic(progress, x) {
return Math.pow(2, 10*(progress-1))*Math.cos(20*Math.PI*x/3*progress);
}
Seventh
/* EaseIn、EaseOut、EaseInOut, 需要结合bounce函数 */
/* EaseIn start */
function makeEaseIn(delta) {
return function(progress) {
return delta(progress);
}
}
var bounceEaseIn = makeEaseIn(bounce);
/* EaseIn End */
/* EaseOut start */
function makeEaseOut(delta) {
return function(progress) {
return 1-delta(1-progress);
}
}
var bounceEaseOut = makeEaseOut(bounce);
/* EaseOut End */
/* EaseInOut start*/
function makeEaseInOut(delta) {
return function(progress) {
if (progress < 0.5) {
return delta(2*progress)/2;
} else {
return (2-delta(2*(1-progress)))/2;
}
}
}
var bounceEaseInOut = makeEaseInOut(bounce);
/* EaseInOut End*/
光说不练假把式
下面我们来举2个例子,我还会使用CSS3做出相同的效果
以上难免有瑕疵之处,欢迎大家找茬! 嘿嘿~~~