Animation

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我们可以不输入*/
}

下面来两幅图给大家加深加深印象。
example1.jpg
看到这里,是不是有人想说,我擦,这TM不是物理嘛。嗯··没错,这应该就是高一的运动,从图我们可知,上图为匀速运动,下图为变速(加速)运动。这TM你到底想给我们展示什么啊,别急,嘻嘻,从图我们可以知道Y轴的height是受X轴progress的值绝对的(这里的相关知识,我就不解释了,想了解的请翻回高中物理书籍),而且height值受progress值影响是有蓝色那条线决定的,so,下面我将带给大家有关蓝线的相关知识,前方数学知识颇多,厌者慎入。

咱们先来个霸气的标题,Math,the function of progress delta

大家都知道有哪些函数图形吗?直线?抛物线?曲线?,下面我们一起来回顾下吧,惯例,上图!

example2.jpg

由于本人数学功底一般,那么我就直接上函数了,大家准备好了吗?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做出相同的效果


以上难免有瑕疵之处,欢迎大家找茬! 嘿嘿~~~