就像許多開發者確信的那樣,在Web上使用CSS實現動畫並不是唯一的方式,我們也可以使用JS來實現,並且JS還有一些CSS無法替代的優勢。
然而拋開JS而選擇CSS來實現動畫,將以樣式表內容膨脹,喪失對動畫時間的控制為代價,並且無法靈活地實現基於物理運動模型的動畫設計。
不要誤導我! CSS動畫在Web中扮演重要的角色-----獨自的實現動畫或是同JS協作實現。 特別的,CSS在一些簡單基本的動畫交互上表現的特別好,比如hover和focus等。(作者的意思是:客觀的看待CSS動畫和JS動畫,他們各有優點)
然而,對於幾乎所有事情,JS都是不錯的選擇,因為他的能力太強大了。
如果我說JS的動畫性能比CSS出色,你可能不會相信我。可能你曾經有使用jQuery設計動畫的糟糕經歷,比如動畫出現抖動、不平滑,然后草率地歸咎於JS語言。
完全不對,不要混淆JS和jQuery這倆種不同的生物。
jQuery 是由許多原生JS寫的函數組成的庫,就像C++的標准庫一樣。jQuery原本不是以動畫引擎為目標設計的,而是為了使煩人的DOM操作變得方便高效(效果確實令人驚訝).
幸運的是目前就有一些開源的動畫庫,使得你可以繞開jQuery去利用原生JS那令人驚嘆的魔力。通過這些動畫庫,您可以建立一個可控的動畫工作流,而且這一切都基於能大幅提升網站動畫性能的特征層之上。
我將帶領你快速地了解Velocity.js,以便於你設計炫目平滑並且易配置的動畫。
What is Velocity.js?
Velocity專為動畫而設計 ,簡單易用,功能強大,廣泛地被一些主流公司所使用(包括Tumblr, Microsoft and WhatsApp)。並且Velocity 是基於MIT許可協議的開源庫。
Velocity模仿了jQuery的語法,可以完美地同jQuery協作,當然也能獨立地使用,所以對你來說應該很容易學。由於jQuery使用普遍,我也將向你展示Velocity如何同它協作。
Note: 為了提高你所有動畫的性能,只需要簡單地將目前jQuery的animate()函數調用換成velocity(),因為Velocity將原來jQueryanimate()函數的語法和功能在velocity()函數內部都做了解釋映射,所以能兼容以前animate()的使用方式(velocity()還擴展了animate()的功能)。但即使是這樣的一個小改變,也能使你的網站有一個顯著的性能提升。
Velocity還有許多需要了解的地方。在我們深入之前,讓我們快速地了解一下他能干什么,以便讓你明白他的價值。
下面是一些不可能用CSS簡單實現的JS動畫。
Page Scrolling
現在有一個流行的Web設計,即在一個長頁面中有序放置所有內容,只需輕微滑動一下鼠標,窗口就會平滑地滾動到恰當的頁面區域,而不是像傳統一樣導航到另一個不同的頁面。這是JS動畫最流行的一種應用,並且無法用CSS實現。
而在Velocity里,你只需在目標元素上調用velocity()方法並傳入"scroll"命令和過渡時間:
$element.velocity("scroll", 1000);
這個方法將使瀏覽器滾動到選定的元素(jQuery對象,$element),過渡時間為1000ms。僅使用jQuery實現這個功能也會很復雜,而且將用到多個函數操作。
對於這條代碼不太明白也沒有關系;我們將在了解velocity幾個巧妙的功能之后慢慢弄懂他。
Animation Reversal
在jQuery中,想要使元素恢復成動畫運行之前的狀態,你必須手動的設置元素原來的屬性值,比如:
$element.animate({ width: "100px" }, 400); // 又使元素在400ms內回復成原來50px的寬度 $element.animate({ width: "50px" }, 400);
相較地,在Velocity里只是一個運行"reversr"命令:
// 先將寬度變到100px $element.velocity({ width: "100px" }, 400); //在400ms內回到原來的狀態 $element.velocity("reverse");
$element.velocity("reverse");這條命令將使$element回到運行$element.velocity({ width: "100px" }, 400);前的狀態,而你不用手動的去設置目標 width (50px).
Physics-Based Motion
現實世界的運動模型既不是線性的也不是平滑的。它有快速的部分,有慢的部分,可能存在摩擦,甚至需要考慮重量。使用JS可以很好地模擬這些運動,並且看起來非常的自然。而線性的運動效果看起來則非常機械,不怎么中看。
為了方便模擬現實世界的運動,Velocity提供彈性動畫功能(spring),以一個張弛度(默認500)和一個摩擦系數(默認值20)作為他的參數(參考Velocity的文檔獲取更多信息)
Example:
$element.velocity({ width: "100px"}, [ 1000, 40 ]);
較高的張弛度將提高整體速度和動畫的反彈力度,較小的摩擦系數將提高動畫結束時的速度。(較大的摩擦系數將使動畫快速減速)。調整這些值會讓每個動畫獨一無二,逼真並且有趣。(具體操作一下感覺更直觀)
上面那個示例運行起來應該非常快,非常靈動(因為設置了較大的張弛度),並且將快速減速,在接近動畫末尾的時候速度將變得很慢。(因為設置了較大的摩擦系數)。
PS:小編在這里解釋一下,spring是動畫選項中easing的一個可選值,至於easing是什么在后面有介紹。這里僅僅解釋一下spring到底是什么玩意兒。准確的講spring對應一個JS函數,而這個函數描述的是一個運動模型,什么模型呢?答案是彈簧振子模型,想必大家初中的時候就做過這種物理題了。spring的倆個參數---張弛度和摩擦系數,其實就對應彈簧的初始彈性勢能和地面的摩擦系數。大家自己都可以把這個模型寫出來。
Okay great, so how do I use it?
已經聽夠他能做什么了!今天讓我們來探究一下怎么去用它。就像我之前提到的一樣,Velocity可以獨立使用,也可以和jQuery一起使用以獲得一個快速高效的結果(因為jQuery使得選擇元素變得非常容易)。
第一步是下載Velocity.js,然后包含到你的頁面中去(原文的敘述考慮到文檔是否解析完畢的問題,特別提到應將它放到</body>之前)
Example:
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script><script src="//cdn.jsdelivr.net/velocity/1.1.0/velocity.min.js"></script>
Note: 如果你正在使用jQuery,確保載入jQuery的script標簽出現在載入velocity的script標簽之前,因為velocity需要根據是否使用jQuery來調整他的API。一旦使用了velocity,你可以在使用jQueryanimate的地方使用它的基本功能。然而想要充分使用它的強大功能的話還有幾個附加設置。比如animation reversals, transforms, spring physics, chaining, and color animations(所有這些將在下面講到)。但這還不是所有,查看文檔獲取更多的信息。
現在讓我們看看velocity真正的語法到底是什么樣的。(之前都是類jQuery的)
Arguments
Velocity 接收一個或更多的參數,只有第一個參數是是強制要求的,它可以是一個命令(就像上面例子中的”scroll”),或者是由CSS屬性值組成的對象(這些值是動畫的目標值):
$element.velocity({ opacity: "50%", left: "500px"});
第二個參數是由動畫附加選項組成的對象,比如過渡時長,張弛度,延時還有回調函數。
Data Object
// 200ms之后在200ms的時間內,透明度變到50% $element.velocity({ opacity: "50%" }, { delay: 200, duration :200 });
另外作為一種可選的快捷方式,你可以以任何順序以逗號隔開的形式傳遞時長,張弛度(easing)和回調函數中的一個或多個參數,然而如果你想再傳入其他動畫選項的話必須使用數據對象的形式,而且這倆種方式不能混合使用。對於這里小編舉幾個例子說明:
//200ms的時長,easing是swing,最后加個回調函數 $element.velocity({left:”1000px”},200,”swing”,function(){console.log(“ok”)}); //等價於$element.velocity({left:”1000px”},{“duration”:200,”easing”:”swing”,”complete”:function(){console.log(“ok”);}) //下面這個用法是錯的,倆種風格不能混用 $element.velocity({ left: "50px" }, 500, "ease-in-out", function () { alert("done") }, { delay: 200 }); //改為: $element.velocity({left:”50px”},{“easing”:”ease-in-out”,”duration”:500,”complete”:function(){alert(“done”);}});
Note: 第二類參數是可選擇的(原文是第二個參數,但從上面的例子可以看出可以是不止倆個參數,從參數分類上卻恰好是倆類,所以小編這里將其譯為第二類(properties和options倆類,在其官方文檔中可以看出來)),因為對於那些重要的屬性都有默認值,比如easing的默認值是swing,duration的默認值是400ms。所有其他的動畫選項都是可選的。
同時你只能為每一個CSS屬性設置一個值,所以 “padding:’10px 15px’”這樣的設置是不合法的。替代做法是單獨設置每一個分屬性:{paddingLeft:”10px”,paddingTop:”15px”,….}。這樣不僅表達清晰,而且意味着你可以特別指定每一個css分屬性的值,而不是只設置一個整體的,給予了你足夠的空間定制動畫。
Note: 有多個單詞描述的CSS屬性(比如font-size和padding-left)必須使用駱駝拼寫法表示(fontSize&&paddingLeft).
Property values
如果CSS屬性值沒有給定確切的單位,那么時間默認是:ms,長度默認是px,角度默認是deg。為了表達清晰最好還是顯示注明單位,那樣以后再看代碼時也容易理解。如果有一個值不僅僅由數字表示,那么必須加引號。比如:duration:500(默認是500ms)是合法的,但是duration:500ms就不合法,必須加上引號:duration:”500ms”.
JS動畫運許傳入簡單的表達式作為CSS的屬性值,但這些表達式只限於:+=,-=,*=,/=,表示目標值在其本來的值的基礎上加多少,減多少,乘多少,除多少,任何其他的表達式是不允許的。實例:
$element.velocity({ width: "+= 50px", // Adds 50px to the current width value eight: "/= 2" // divides the current height value by two });
表示動畫完成后width比原值大50px,height變為原來的二分之一。
在Velocity動畫引擎里使用這些快速功能保證了動畫的邏輯可讀性,使代碼簡潔清晰(消除了值的手工計算),而且向Velocity引擎提供更多有關於你動畫意圖的信息將有助於提高動畫的性能。動畫邏輯包含的越多,Velocity就能更好地提高代碼的性能。
Chaining
Velocity的鏈式調用即在同一個元素上一個動畫完成之后馬上進入另一個動畫,這樣一個一個的執行下去:
$element .velocity({ width: "500px", height: "300px"}) .velocity({ opacity: 0 });
等價於:
$element.velocity({ width: "500px", height: "300px"}); $element.velocity({ opacity: 0 });
就如之前提到的一樣,這允許你不需要任何手動的計算,就能使那些復雜的、有時間限制的多級動畫如當初計划的一樣,一個接一個的執行。
Easing
我已經在文章里多次提到easing這個詞了,或許你一直想弄明白它究竟是什么意思。easing是一些數學函數,他們決定了一個動畫在不同階段的速度(其實就是物理的運動模型)。比如:ease-in-out表示先加速再減速。linear表示勻速。
你可以在easing選項里指定easing的類型;
$element.velocity({ top: 100 }, { easing: "ease-in-out" });
easing也是使用之前提到的彈性動畫的一種方式。你可以只傳入spring來使用它(默認張弛度500,阻力系數:20),也可以像下面那樣手動指定參數來使用:
$element.velocity({ width: 500 }, { easing: [ 250, 10 ] });
easing還有很多復雜難懂的內容,因為文章篇幅的原因,也就只介紹到這里。更多的信息可以從官方文檔中獲取。
Color
Velocity 允許制作基於顏色變換的動畫,比如:color,backgroundColor,borderColor還有outlineColor.所有這些顏色的值只允許是16進制的字符串(黑色:#000000 , 臉譜藍:#3b5998(for Facebook blue) ).也許你想使用rgb格式的顏色設置,甚至指定顏色透明度(值介於0到1),只需簡單地在CSS顏色名后面加上“Red”,“Green”,”Blue” 或者“Alpha”即可:
$element.velocity({ borderColor: "#f06d06", backgroundColorAlpha: 0.8,//背景顏色透明度變到80% colorBlue: 200//rgb 方式 });
Scrolling
如早些說過的一樣 ,scroll命令將促使頁面滾動到指定元素的上邊緣,你可以向其他動畫一樣傳遞同樣的附加選項,並且同樣支持鏈式調用。
$element .velocity("scroll", { duration: 1000 }) .velocity({ opacity: 1 }); //默認的滾動沿y軸方向,想改到x軸方向的話可以使用axis選項: $element.velocity("scroll", { axis: "x" });
Velocity允許你設置窗口滾動后元素上邊緣距窗口上邊緣的距離,你只需設置offset選項即可完成:
// 滾動之后窗口上邊緣將位於元素上邊緣之上100px的地方 $element.velocity("scroll", { duration: 1000, offset: "-100px" }); //滾動之后窗口上邊緣將位於元素上邊緣之下100px的地方 $element.velocity("scroll", { duration: 1000, offset: "100px" });
Transforms
想要結合CSS和JS設計動畫? 設置一些CSS變換規則,允許你做一些2D或3D的動畫,比如平移,擴大,旋轉。注意這些變換不會影響元素在網頁中的位置,也不會影響該元素周圍 的元素在頁面中的位置。 Velocity支持下面的變換:
- translateX: 從左向右沿x軸移動元素
- translateY: 從上到下沿y軸移動元素
- rotateZ: 關於z軸旋轉元素
- rotateX: 關於x軸旋轉元素(看起來由里向外)
- rotateY: 關於y軸旋轉元素(由左到右)
- scaleX: 成倍數改變元素寬度
- scaleY: 成倍數改變元素高度
$element.velocity({ rotateZ: "90deg", // rotate clockwise 90 degrees scaleX: 2.0 // double the width });
Going Forward
動畫使得靜態頁面更具交互性,更加栩栩如生,而JS動畫則是最好的實現方式。 CSS動畫可選的功能有限,更新慢;而對於JS動畫,在開源世界則有一大堆庫和插件,並且維護地很好。使用這些JS工具將使得你的動畫設計更具有可能性。
除了在這里演示的外,Velocity還有很多其他的功能,小編強烈建議看看它的文檔。現在就開始動手吧!:)
Bonus!
最后,額外的倆點:查看這個教程了解怎樣使用Velocity的UI包來改善用戶界面。還有您也可以查看這里的velocity 示例。
來自:http://www.w3ctech.com/topic/1403