JavaScript中动画与特效的实现原理

原创 zhongxiaoyou 随笔 js应用 245阅读 2018-01-30 20:01:21 举报

一、JavaScript中的动画原理
动画效果可以通过两种方式来实现:一种是通过JavaScript间接的操作css,每隔几秒执行一次,另外一种是利用纯css实现,该方法在css3成熟后广泛应用.这里主要将js里面的动画:

  1. JavaScript动画用的最多的是setInterval()、setTimeout()和requestAnimationFrame():
  2. 1 setTimeout()和setInterval ()主要是自身会执行动画效果,它们在里面放入function和时间参数,然后既可以设置事件;
  3. 2 requestAnimationFrame(回调函数):像setTimeout、setInterval一样,requestAnimationFrame是一个全局函数。调用requestAnimationFrame后,它会要求浏览器根据自己的频率进行一次重绘,它接收一个回调函数作为参数,在即将开始的浏览器重绘时,会调用这个函数,并会给这个函数传入调用回调函数时的时间作为参数。由于requestAnimationFrame的功效只是一次性的,所以若想达到动画效果,则必须连续不断的调用requestAnimationFrame,就像我们使用setTimeout来实现动画所做的那样。
    requestAnimationFrame函数会返回一个资源标识符,可以把它作为参数传入cancelAnimationFrame函数来取消.requestAnimationFrame的回调,跟setTimeout的clearTimeout很相似。 可以这么说,requestAnimationFrame其实就是setTimeout的性能增强版。
    javascript 代码

1.3简单动画的问题
1.3.1 setTimeout和setInterval的深入理解
setTimeout():如下面这段代码,输出结果其实是1 2 3,而不是 1 3 2,因为setTimeout()其实在执行的时候会先存储这个结果但不会立即输出(即使时间间隔是0也这样)而是等待页面加载完成后再输出结果
javascript 代码

1.3.2 简单动画的变慢问题
当setTimeout、setInterval甚至是requestAnimationFrame()在循环里面要做很长的处理时,就会出现动画时间变慢的结果,使它本该在固定时间内结束而结果却是不尽人意的延迟
实例1:让滑块自动向右移动
javascript 代码

实例2:
javascript 代码

1.4 使用动画的正确姿势
其实是 “位移”关于“时间”的函数:s=f(t)
动画变慢的结果其实是采用增量的方式来执行了动画,为了更精确的控制动画,更合适的方法是将动画与时间关联起来
javascript 代码

动画通常情况下有终止时间,如果是循环动画,我们也可以看做特殊的——当动画达到终止时间之后,重新开始动画。因此,我们可以将动画时间归一(Normalize)表示:
javascript 代码

示例1:用时间控制动画周期精确到2s中
javascript 代码

示例2:让滑块在2秒内向右匀速移动600px
javascript 代码

时间V.S增量

二、常见动画效果实现
2.1 匀速水平运动
用时间来控制进度 s=S∗p
2.2 匀加速(减速)运动
1)加速度恒定,速度从0开始随时间增加而均匀增加。
2)匀加速公式:大写S:要移动的总距离 p:归一化的时间进度 s=S∗p*p
javascript 代码

3)匀减速运动公式:s=S∗p∗(2−p)
javascript 代码

2.3 水平抛物运动
匀速水平运动和自由落体运动的组合。
javascript 代码

2.4 正弦曲线运动
正弦运动:x方向匀速,垂直方向是时间t的正弦函数
javascript 代码

2.5 圆周运动
圆周运动公式:x=R.sin(2∗π∗p),y=R.cos(2∗π∗p)
javascript 代码

三、动画算子(easing)
对于一些比较复杂的变化,算法也比较复杂,就要用到动画算子。动画算子 是一个函数,可以把进度转化成另外一个值。其实也就是一种算法。
我们总结一下上面的各类动画,发现它们是非常相似的,匀速运动、匀加速运动、匀减速运动、圆周运动唯一的区别仅仅在于位移方程:
1.匀速运动:s=S∗p
2.匀加速运动:s=S∗p*p
3.匀减速运动:s=S∗p∗(2−p)
4.圆周运动x轴:x=R∗sin(2∗PI∗p)
5.圆周运动y轴:y=R∗cos(2∗PI∗p)
我们把共同的部分 S 或R 去掉,得到一个关于 p 的方程 ,这个方程我们称为动画的算子(easing),它决定了动画的性质。

1.匀速算子:e=p
2.匀加速算子:e = p*p=p^2
3.匀减速算子:e=p∗(2−p)
4.圆周算子x轴:e=sin(2∗PI∗p)
5.圆周算子y轴:e=cos(2∗PI∗p)

一些常用的动画算子
javascript 代码

四、使用面向对象封装动画
为了实现更加复杂的动画,我们可以将动画进行 简易 的封装,要进行封装,我们先要抽象出动画相关的要素:

动画生命周期:开始、进程中、结束
javascript 代码

初步修改版:
javascript 代码

终极版:
javascript 代码

五、逐帧动画
有时候,我们不但要支持元素的运动,还需要改变元素的外观,比如飞翔的小鸟需要扇动翅膀,这类动画我们可以用逐帧动画来实现:
html 代码

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复