第 1 章 JavaScript动画的优势

第 1 章 JavaScript动画的优势

在本章中,我们将会对比CSS动画和JavaScript动画的优劣,同时介绍JavaScript动画的特点和工作流方面的优势。

简而言之,我们提供所需的背景知识,帮助你理解即将在本书中学到的JavaScript的任何知识。

1.1 JavaScript动画与CSS动画

在网页开发圈子里有一种误解,那就是认为CSS动画是网络中唯一可以实现高性能动画的方法。这种误解使很多开发人员干脆放弃了用JavaScript实现动画,而这会迫使他们做出以下行为。

  • 在样式表中管理有关用户界面(UI)互动的所有内容,这样代码很快会变得难以维护。

  • 牺牲实时动画的定时控制,因为它只能通过JavaScript实现。(在移动应用中会看到需要响应用户拖拽操作的UI。在为这些UI设计动画时,必须使用定时控制。)

  • 放弃基于物理的动效设计,这会使网页上的元素无法表现得像真实世界中的物体一样。

  • 不再支持旧浏览器版本,而实际上旧版本浏览器在世界范围内仍大量使用。

事实是,基于JavaScript的动画与基于CSS的动画一样快。之所以人们错误地认为CSS动画在性能上有显著优势,那是因为人们通常拿它与jQuery的动画性能对比,后者确实非常慢。然而,一些彻底绕开jQuery的JavaScript动画库通过与页面的顺畅交互表现出了非凡的性能。

注意 Velocity.js是一个著名的动画库,本书自始至终都在使用它。这是个轻量级的库,但是功能却异常丰富。另外,它与jQuery的动画语法类似,能够大幅降低学习难度。

当然,CSS非常适合实现悬停状态的动画效果(例如:当鼠标位于链接上方时,链接变成蓝色),这也是通常情况下基本的网页所包含的动画。CSS过渡效果可以直接在已有的样式表中实现,这样开发人员就可以避免使用冗余的JavaScript库,使页面不再臃肿。另外,CSS动画不费吹灰之力就可以呈现上佳表现。

但是,本书将会说明为什么JavaScript对于动画来说经常是更好的选择,简单的悬停效果除外。

1.2 强大的性能

JavaScript与jQuery常被错误地混为一谈。JavaScript动画很快,是jQuery让它慢了下来。尽管jQuery非常强大,但它并未被设计成高性能的动画引擎。它没有避免“布局颠簸”的机制,这使浏览器在动画处理过程中,过分忙于布局处理的工作。

另外,由于jQuery的代码库除了实现动画以外还有许多其他目的,因此它的内存消耗会在浏览器内触发垃圾回收,导致动画在不可预知的情况下卡壳。最后,由于jQuery团队奉行一个崇高的追求,那就是帮助新手避免用坏代码毁了他们的UI,因此jQuery放弃了被经常推荐的做法,拒不使用requestAnimationFrame()函数,但另一方面浏览器竞相支持该函数,因为它可以为网络动画大幅提升帧率(frame rate)。

一些彻底绕开jQuery的JavaScript动画库通过与页面的顺畅交互而表现出非凡的性能。其中之一是著名的动画库,也是本书自始至终使用的Velocity.js。这是个轻量级的库,但是功能却异常丰富。另外,它与jQuery的动画语法类似,能够大幅降低学习曲线。

有关性能的问题,我们会在第7章中深入探讨。通过学习浏览器渲染性能的微妙差异,你能够打下坚实的基础,为所有的浏览器和设备创建可靠的动画效果,不论这些浏览器和设备的处理能力如何。

1.3 功能

追求速度当然不是使用JavaScript的唯一理由,它还具有一大堆其他同等重要的功能。让我们大致看几个JavaScript所独有并值得关注的动画功能。

1.3.1 页面滚动

页面滚动是基于JavaScript的动画最为流行的应用之一。最近,网页设计的趋势是创建很长的页面。随着页面向下滚动,让每一部分新的内容自动滚到可视区域中来。

例如Velocity这样的JavaScript动画库提供了一种将元素滚动至可视区域的简单函数:

$element.velocity("scroll", 1000);

以上代码通过使用Velocity的"scroll"命令让浏览器用1000毫秒的时间滚动至$element的上方边缘位置。注意,Velocity的语法与jQuery的$.animate()函数几乎一模一样,这会在本章后面的部分进行详述。

1.3.2 动画反转

动画反转是用于撤消元素前一个动画的简便方法。通过调用反转命令,你会使元素以动画形式变动回上一个动画开始之前的值。反转的常见用途是动态显示一个模态对话框,然后在用户点击“关闭”后再将其隐藏起来。

如果想实现动画反转,但却没有优化工作流程的话,你会这么做:把上次在每个元素上动态显示的特定属性跟踪记录下来,以备后续反转动画之用。但是在UI代码中跟踪之前的动画状态很快就会变得难以控制。与之形成鲜明对比的是Velocity,通过reverse命令就可以记住一切。

与Velocity中scroll命令的语法相似,reverse命令也是通过将"reverse"作为Velocity的第一个参数传入而调用的:

// 第一个动画:设置元素的opacity属性变动至0的动画
$element.velocity({ opacity: 0 });
// 第二个动画:设置元素的opacity属性值变动回初始值1的动画
$element.velocity("reverse");

当谈到JavaScript的动画定时控制时,就不仅仅是反转那么简单了:JavaScript还允许对全部正在运行的动画进行全局减速或加速。第4章会介绍这一强大功能的相关知识。

1.3.3 基于物理的动效

动效设计中的物理原则反映了成就优秀用户体验(UX)的核心原则:那就是伴随着用户的输入,界面出现自然的反应。换言之,界面设计遵从物体在真实世界中的运动规律。

在Velocity中有一个简单且强大的入门级物理动效,即基于弹簧运动原理的缓动类型。(我们会在下一章详细探讨缓动的概念。)使用典型的缓动选项,可以传入一个与预先定义的缓动曲线(例如,"ease""easeInOutSine")相对应的字符串。相反,弹簧物理缓动类型接受一个含有两个项的数组作为参数。

// 使用500个张力单位和20个摩擦力单位的弹簧物理缓动,设置将元素的宽度变动至"500px"的动画
$element.velocity({ width: "500px" }, { easing: [ 500, 20 ] });

缓动数组中的第一项代表弹簧的张力,而第二项代表摩擦力。张力值越大,动画的总体速度就越快,总体反弹幅度就越大。摩擦力值越低,动画尾部振动的速度就越快。通过调整这些数值,可以为页面上每一个动画实现独特的运动效果,这有助于强化不同行为之间的差异。

1.4 易维护的工作流

设计动画是一个不断试验的过程,需要反复修改时间和缓动值才能在页面上达到和谐统一的效果。然而无可避免的是,就当你已经将设计优化到最佳时,客户跳出来要求大改。这种情况下,代码是否易于维护就变得至关重要了。

基于JavaScript来解决这一工作流难题是非常优雅的,这将会在第4章中详细阐述。在这里先简要解释一下:有技术可以将一个个JavaScript动画链接起来,而且每个动画都有各自不同的持续时间和缓动效果等,这样其中一个动画的定时不会影响其他动画。这就意味着不用重新计算,就可以把某个动画的持续时间改来改去,还能轻易将动画设置为同时进行或是顺次进行。

1.5 小结

当使用CSS设计动画时,肯定要受限于CSS规范所提供的那些功能。但JavaScript是一门编程语言,具有编程语言的天然属性,其第三方程序库可以对动效设计进行无限的逻辑控制。动画引擎利用这一点来提供强大的功能,不仅可以大幅优化工作流,还能拓展交互动效设计的可能性。而这正是本书的目的所在:用尽可能高效的方法设计优美的动画效果。

下一章介绍怎样使用本书选择的JavaScript动画引擎Velocity.js。通过掌握Velocity.js,将会了解如何使用我们前面已经介绍的一些功能以及其他更多内容。

目录