在客观的物体运动中,以匀速直线运动为例,我们可以同时用速度与时间曲线或位移与时间曲线来描述物体的运动:
不管是用速度与时间的关系还是位移与时间的关系来描述客观物体的直线运动,物体的状态都是一致的,这是因为客观物体的运动总是沿着人无法改变的客观时间轴进行变化,在时间轴上的任意一点,总有特定的速度以及位移与之对应。
而在网页动画中,虽然它也呈现为运动,但是我们不能用客观物体的运动规律去描述它。我认为原因主要是 动画的本质不是运动,仅仅是基于定时器对元素状态进行的瞬间改变 。以一个简单的元素进行水平匀速偏移的动画效果为例,要实现这个动画,只要用一个定时器在一个固定的时间间隔,重新设置元素的x轴偏移量即可,大概用图可以描述如下:
图中t1~t6代表定时器回调函数执行的时刻。在这个效果中,元素的偏移位置将在定时器每次执行的时刻发生变化,而在相邻的两个执行时刻之间,元素的偏移位置是不变的。我们看到的动画,仅仅是因为定时器间隔时间太短,从视觉上感知不到这段时间的过程,如果将定时器间隔加到足够长,我们就能看到元素在间隔时间内的状态了。
正因动画不是运动,所以我们在尝试理解一些动画过程的时候,不能用运动规律去思考。比如我们该如何去理解动画停止那一刻的状态?还以前面提到的这个动画效果为例,当把定时器清掉的时候,动画瞬间停止,对于元素而言,它的动画速度将骤变为0,如果我们类比到客观的物体运动,总是会想当然地以为元素的动画也应该先有个减速的过程才能停止下来,要是这样想,就没办法理解元素动画停止时骤停的原理了。但是当我们从动画的本质去思考这个问题的时候,就很好理解了,因为定时器是元素在动画过程中发生状态改变的唯一要素,当定时器不起作用的时候,就没有外在的力量去改变元素的状态了,它还怎么能动呢?
尽管动画不是运动,我们还是希望找到一个方式,能够很好的控制动画的快慢,以便打造更加流畅,更加逼近客观世界的动画效果。当提到快慢,就很容易想到速度,因为在客观物体运动中,速度就是用来描述运动快慢的要素。而且用速度的规律来控制动画的快慢,看起来也很好理解和实现。将前面的的例子再具体一点,假如我们想实现一个元素在1秒内往右匀速偏移120px的动画效果,那么只要用定时器控制元素每次往右偏移固定的量即可,这里面定时器每次执行给元素添加的偏移量,就是我们用来控制动画的速度。如果我们以16ms作为定时器的间隔,那么这个动画的速度可以通过: 120px / (1000ms / 16ms) 求得(约等于 2px),也就是说只要定时器每次执行的时候将元素往右偏移2px就能实现我们要的效果。简单代码实现如下:
doctype html > html lang ="en" > head > meta charset ="UTF-8" > title > Document title > head > body > div id ="box" style ="width: 100px;height: 100px;background-color: goldenrod" > div > br > button type ="button" onclick ="start()" > 开始 button > body > script > var box = document.getElementById( ' box ' ); function start() { var duration = 1000 ; // 动画时长 var s = 120 ; // 总的偏移量 var cur_s = 0 ; // 当前偏移总量 var p = 16 ; // 定时器间隔 var speed = s / (duration / p); // 速度 var count = 0 ; var start_time = new Date().getTime(); var timer = setInterval( function (){ if (cur_s >= s) { clearInterval(timer); console.log( ' 动画运行时间(ms): ' + ( new Date().getTime() - start_time)); return ; } count ++ ; cur_s = speed * count; box.style.transform = ' translateX( ' + cur_s + ' px) ' ; },p); } script > html >
查看更多关于为什么不能用速度与时间的关系去实现动画的详细内容...