请马上登录,朋友们都在花潮里等着你哦:)
您需要 登录 才可以下载或查看,没有账号?立即注册
x
CSS关键帧动画可以让盒子匀速旋转,但倘若引入缓动运动(增减速运动),不论我们通过改变旋转角度还是动画运行时长加以实现,得到的结果都是卡顿或跳帧——旋转对象在上下两个数值交替过程中的衔接瞬间难以做到自然过渡,即便加入合适的 transition 属性值。下面示例,初始时第一个光盘和第二个光盘都匀速旋转,每次点击光盘1都会随机改变其运行时长,每次点击光盘2都改变其旋转角度,肉眼可以发现,它们在相应数值改变时的旋转过渡并不平滑,或前后跳帧,或卡顿。
或许加入一些复杂的算法可以解决上面存在的问题,但处理起来很繁琐。所以,连贯运动着的缓动运动还是建议抛弃关键帧动画,采用JS定时器来动态驱动transform rotate,实际上是改变旋转的角度——给旋转对象在旋转过程中施以不同的角度。JS定时器有两大类,一类是 setInterval 和 setTimeout,另一类是基于屏幕刷新率的 rAF 即 requestAnimationFrame(请求关键帧动画)API。下面的两个光盘也都在匀速旋转,第一个是通过setTimeout驱动,第二个是通过 requestAnimationFrame 驱动,每次单击它们都会分别改变旋转速度,看一看旋转速度改变后的光盘旋转过渡状态,:
肉眼不易看出二者在旋转速度改变之后的缓动衔接有什么区别,但如果多点几次、细细观察,还是能感觉到第二个光盘的整体旋转与变速后的衔接更自然、平滑,道理与各自的工作机制有关:setTimeout通过CPU时钟按指定间隔时间驱动对象的旋转,rAF则通过显卡的刷新率来实现驱动而不是通过计时。我们知道,计时驱动下的两个动作间衔接总是有间隔的,即便我们用了肉眼不能觉察的 1000/60 的间隔时间;而rAF,只要我们正在使用的显示器没有异常(刷新率在60赫兹上下),由它驱动的动画我们就看不出卡顿或跳帧从而达到平滑过渡的效果。
set...类和 rAF类也都有缺点,主要有:一是,多次调用,它们都会比实际定义的速度快一点,动画运行的时间越长这种现象就会更明显,rAF尤甚(解决方法是及时通过回调ID清除,clearSetTimeout(id)/clearSetInterval(id)和cancelAnimationFrame(id));二是,set...类计时的精准度不稳定,长时间运行需要定时通过时间戳进行校对,而rAF类一切依赖系统的刷新率,动画运行的实际速度与刷新率呈正比关系——这意味着我们事实上并不能在代码中真实有效地按自己的预期控制动画的运行速度,除非我们也引入时间戳的算法来进行运算、控制。尽管如此,对于普通的动画,例如本帖中驱动光盘盒子旋转,定时器的使用仍然是合适的。
|