- 原文地址:Integrating Third-Party Animation Libraries to a Project - Part 1
- 原文做者:Travis Almand
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:TUARAN
- 校对者:lihaobhsfer
建立以 CSS 为基础的动画多是一个挑战。它们多是复杂且耗时的。你是否须要在时间紧迫的状况下调整出一个完美的动画(库)来推动项目?这时,你该考虑使用一个拥有现成的动画插件的第三方 CSS 动画库。但是,你仍然会想:它们是什么?它们提供什么?我如何使用它们?javascript
咱们来看看吧。css
曾经有一段时间,hover 状态与如今它能提供的功能相比不值一提。实际上,对于在元素上浮动的光标进行响应的想法能够说是不存在的。对此,实现该特性的不一样方法被提了出来。在某种程度上来说,这个小特性为 CSS 可以在页面上的元素建立动画打开了大门。随着时间的推移,这些特性可能愈来愈复杂,致使 CSS 动画库的产生。html
Macromedia’s Dreamweaver 于 1997 年 12 月推出,并提供了一个简单的功能,即悬停时的图像变换。这个特性是经过一个 JavaScript 函数实现的,该函数被编辑器嵌入到 HTML 中。这个函数被命名为 MM_swapImage()
,而且它已经成为一个 web 设计的民间传说。这个脚本易于使用,即便在 Dreamweaver 以外也是如此,它的流行性使得它直到今天还在使用。在本文的初步研究中,我在 Adobe’s Dreamweaver(Adobe 于 2005 年收购了 Macromedia)帮助论坛上发现了一个与此功能相关的问题。前端
JavaScript 函数将根据 mouseover 和 mouseout 事件更改 src 属性,从而将一个图像与另外一个图像交换。实现时,它看起来是这样的:java
<a href="#" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('ImageName','','newImage.jpg',1)">
<img src="originalImage.jpg" name="ImageName" width="100" height="100" border="0">
</a>
复制代码
按照今天的标准,用 JavaScript 实现这一点是至关容易的,咱们中的许多人实际上均可以在睡梦中完成这一点。可是,考虑到 JavaScript 在当时(建立于 1995 年)仍然是一种新的脚本语言,并且有时在不一样浏览器之间的外观和行为都有所不一样。建立跨浏览器 JavaScript 并非一件容易的事情,甚至不是每一个建立 web 页面的人都编写 JavaScript。(这一点显然已经改变了)Dreamweaver 经过编辑器中的菜单提供了这一功能,而 web 设计师甚至不须要编写 JavaScript。它基于能够从不一样选项列表中选择的一组“行为”。这些选项能够被一组目标浏览器过滤;3.0 浏览器,4.0 浏览器,IE 3.0,IE 4.0,Netscape 3.0,Netscape 4.0。啊,过去的美好时光。jquery
大约在 1997 年,就可根据浏览器版本选择行为。android
Macromedia Dreamweaver 1.2a 中的交换图像行为面板ios
Dreamweaver 首次发布大约一年后,W3C 的 CSS2 规范在 1998 年 1 月的工做草案中提到了 :hover
。它在锚点连接方面被特别提到,可是语言代表它可能被应用于其余元素。在大多数状况下,这个伪选择器彷佛是 MM_swapImage()
的一个简单替代方法的开始,由于 background-image
也在同一草案中。尽管浏览器支持是一个问题,由于在足够多的浏览器正确支持 CSS2 以前,它已经花费了数年的时间,使其成为许多 web 设计人员的一个可行选项。2011 年 6 月,终于有了 W3C 推荐的 CSS2.1,这能够被认为是咱们所知的“现代” CSS 的基础。css3
在这中间,jQuery 出如今 2006。幸运的是,jQuery 在简化不一样浏览器之间的 JavaScript 方面走了很长的路。咱们的故事中有一件有趣的事情,jQuery 的第一个版本提供了 animate()
方法。使用这种方法,你能够在任什么时候候对任何元素的 CSS 属性进行动画的操做;不仅是悬停。因为它的流行,这个方法暴露了在浏览器中嵌入一个更健壮的 CSS 解决方案的须要——这个解决方案不须要 JavaScript 库,由于浏览器的限制,JavaScript 库的性能并非一直都很好。git
:hover
伪类只提供了从一种状态到另外一种状态的生硬转换,不支持平滑的转换。它也不能使元素在像悬停在元素上这样的基本元素以外的变化产生动画效果。jQuery 的 animate()
方法提供了这些特性。它铺平了道路,并一直前进着。在 web 开发的动态世界中,解决这个问题的工做草案在 CSS2.1 的建议发布以前就已经开始了。CSS Transitions Module Level 3 的第一份工做草案于 2009 年 3 月由 W3C 首次发布。第一个工做草案 CSS Animations Module Level 3 是在大体相同的时间发布的。截止到 2018 年 10 月,这两个 CSS 模块仍然处于工做草案状态,固然,咱们已经大量使用了它们。
一开始一个由第三方提供的、仅仅为了一个简单的悬停状态的 JavaScript 函数,逐渐变成了 CSS 中精巧复杂的过渡和动画——这一复杂性,许多开发者都不肯在他们须要快速推动新项目的时候花时间考虑。咱们已经绕了一圈;今天,许多第三方 CSS 动画库已经被建立用来抵消这种复杂性。
在这个新的世界里,咱们能够在网页和应用程序中实现强大、使人兴奋的、复杂的动画。关于如何处理这些新任务,出现了几个不一样的想法。并非一种方法比另外一种更好;事实上,二者之间有不少重叠之处。不一样之处在于咱们如何为它们实现和编写代码。有些是成熟的 JavaScript 专用库,而另外一些则是 css 专用集合。
仅经过 JavaScript 操做的库一般提供的功能超出了常见的 CSS 动画所提供的功能。一般,会有重叠,由于库实际上可能使用 CSS 特性做为其引擎的一部分,但这将被抽象出来,以支持 API。例如 Greensock 和 Anime.js。经过查看他们提供的演示,你能够看到他们提供的内容的范围(Greensock 有一个 CodePen 上的 nice 集合)。它们主要用于高度复杂的动画,但也能够用于更基本的动画。
有一些第三方库主要包括 CSS 类,但也提供了一些 JavaScript,以便在项目中轻松使用这些类。一个库 mic.js 提供了一个 JavaScript API 和能够在元素上使用的数据属性。这种类型的库容许你轻松地使用预先构建的动画,你能够从中选择动画。另外一个库 Motion UI, 打算与 JavaScript 框架一块儿使用。尽管如此,它也适用于相似的概念,即 JavaScript API、预构建类和数据属性的混合。这些类型的库提供了预构建的动画,并提供了一种将它们链接起来的简单方法。
第三种库是只支持 CSS 的。一般,这只是经过 HTML 中的连接标签加载的 CSS 文件。而后应用并删除特定的 CSS 类来使用所提供的动画。这类库的两个例子是 Animate.css 和 Animista。也就是说,这两个特殊的库之间甚至有很大的差别。CSS 是一个完整的 CSS 包,而 Animista 提供了一个光滑的界面来选择你想要的动画代码。这些库一般很容易实现,可是你必须编写代码才能使用它们。这些是本文将重点讨论的库类型。
是的,有这么样的一个模式;毕竟,三条写做的原则无处不在。
在大多数状况下,使用第三方库时须要考虑三种类型的动画。每种类型适合不一样的目的,并有不一样的方法来使用它们。
这些动画被设计成某种悬停状态。它们一般与按钮一块儿使用,但另外一种可能性是使用它们突出显示光标所在的部分。它们还能够用于聚焦状态。
这些动画用于一般位于查看页面的人的视觉中心以外的元素。动画应用于须要注意的显示部分。这样的动画本质上是微妙的,可用于那些在最后须要一些注意,可是本质并不严重的事情。当须要当即集中注意力时,它们也会高度分散注意力。
这些动画一般打算让视图中的一个元素替换另外一个元素,但也能够用于一个元素。这些一般包括用于“离开”视图的动画和用于“进入”视图的镜像动画。想一想淡入淡出。这在单页应用程序中是很常见的,例如,数据的一部分将转换到另外一组数据。
那么,让咱们来看看每种类型动画的例子,以及如何使用它们。
有些库可能已经设置了悬停效果,而有些库则将悬停状态做为其主要用途。其中一个这样的库是 Hover.css,这是一个下拉式解决方案,提供了经过类名应用的一系列悬停效果。不过,有时咱们但愿在不直接支持 :hover
伪类的库中使用动画,由于这可能与全局样式冲突。
对于这个例子,我将使用 Animate.css 提供的tada animation。它的做用主要是吸引注意力,可是对于这个例子来讲,它已经足够了。若是你要查看库的 CSS,你将发现没有要查找的 :hover
伪类。因此,咱们必须让它以咱们本身的方式工做。
tada
类自己很简单:
.tada {
animation-name: tada;
}
复制代码
让它对悬停状态作出反应的一种比较省事的办法是建立咱们本身的类的本地副本,可是稍微扩展一下。一般,Animate.css 是一个下拉式解决方案,因此咱们不必定有编辑原始 CSS 文件的选项;尽管若是你愿意,你能够拥有本身的本地文件副本。所以,咱们只建立须要不一样的代码,其他的代码由库处理。
.tada-hover:hover {
animation-name: tada;
}
复制代码
咱们可能不该该覆盖原来的类名,以防咱们想在其余地方使用它。所以,咱们作了一个变化,咱们能够把 :hover
伪类放在选择器上。如今,咱们只需使用库中必需的animated
类以及自定义的 tada-hover
类来建立一个元素,它将在悬停时播放动画。
若是你不但愿以这种方式建立自定义类,而但愿使用 JavaScript 解决方案,那么有一种相对简单的方法来处理它。奇怪的是,它与咱们前面讨论过的 Dreamweaver 中的 MM_imageSwap()
方法相似。
// Let's select elements with ID #js_example
var js_example = document.querySelector('#js_example');
// When elements with ID #js_example are hovered...
js_example.addEventListener('mouseover', function () {
// ...let's add two classes to the element: animated and tada...
this.classList.add('animated', 'tada');
});
// ...then remove those classes when the mouse is not on the element.
js_example.addEventListener('mouseout', function () {
this.classList.remove('animated', 'tada');
});
复制代码
根据上下文,实际上有多种方法能够处理这个问题。在这里,咱们建立一些事件监听器来等待鼠标通过和鼠标离开事件。这些侦听器而后根据须要应用和删除库的 animated
和 tada
类。正如你所看到的,只需稍微扩展一下第三方库以知足咱们的需求,就能够相对容易地完成。
第三方库能够帮助的另外一种类型的动画是注意力寻求者。当你但愿将注意力吸引到页面的某个元素或部分时,这些动画很是有用。这方面的一些例子能够是通知或未填充的必需表单输入。这些动画能够是微妙的,也能够是直接的。当某件事情须要最终的关注,但不须要当即解决时,这是很微妙的。直接用于如今须要解决的事情。
有些库将动画做为整个包的一部分,而有些库是专门为此目的构建的。Animate.css 和 Animista 都有用于吸引注意的动画。为此目的构建的库的一个例子是 CSShake。使用哪一个库取决于项目的须要以及你但愿在实现它们上投入多少时间。例如,CSShake 已经为你准备好了,你只需根据须要应用类便可。不过,若是你已经在使用 Animate 之类的库。而后,你可能不但愿引入第二个库(用于性能、依赖关系等)。
所以,可使用 Animate.css 这样的库,但须要更多的设置。库的 GitHub 页面有一些示例介绍了如何实现这一点。根据项目的须要,将这些动画实现为吸引注意力的工具很是简单。
对于一种微妙的动画类型,咱们能够有一个只是重复必定数量的次数和中止。这一般包括添加库的类,将 animation iteration 属性应用于 CSS,并等待 animation end 事件清除库的类。
下面是一个简单的例子,与咱们以前看到的悬停状态相同:
var pulse = document.querySelector('#pulse');
function playPulse () {
pulse.classList.add('animated', 'pulse');
}
pulse.addEventListener('animationend', function () {
pulse.classList.remove('animated', 'pulse');
});
playPulse();
复制代码
库类在调用 playPulse 函数时应用。animationend 事件有一个事件监听器,它将删除库的类。一般,这只会播放一次,但你可能但愿在中止以前重复屡次。CSS 没有为此提供一个类,可是为咱们的元素应用 CSS 属性来处理它是很容易的。
#pulse {
animation-iteration-count: 3; /* Stop after three times */
}
复制代码
这样,动画将播放三次才会中止。若是咱们须要更早地中止动画,咱们能够手动删除 animationend
函数以外的库类。库的文档实际上提供了一个可重用函数的例子,用于应用在动画以后删除它们的类;与上面的代码很是类似。甚至能够很容易地扩展它,将迭代计数应用于元素。
对于更直接的方法,让咱们说一个无限的动画,直到用户交互发生后才会中止。让咱们假设单击元素是动画的开始,而后再次单击中止动画。请记住,动画的启动和中止取决于你本身。
var bounce = document.querySelector('#bounce');
bounce.addEventListener('click', function () {
if (!bounce.classList.contains('animated')) {
bounce.classList.add('animated', 'bounce', 'infinite');
} else {
bounce.classList.remove('animated', 'bounce', 'infinite');
}
});
复制代码
很简单。若是应用了库的 "animated" 类,单击元素测试。若是没有,咱们应用库类,这样它就会启动动画。若是它有类,咱们删除它们来中止动画。注意 classList
末尾的 infinite
类。幸运的是,Animate.css 为咱们提供了开箱即用的功能。若是你选择的库没有提供这样的类,那么这就是你须要在你的 CSS:
#bounce {
animation-iteration-count: infinite;
}
复制代码
下面的演示表达了这段代码的行为:
请参阅 Travis Almand@talmand 在 codepen 上的笔记 3rd party animation libraries:attention seekers。
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。