- 原文地址: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、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。