animation-play-state 屬性規定動畫正在運行仍是暫停。css
div { animation-play-state:paused; -webkit-animation-play-state:paused; /* Safari 和 Chrome */ }
瀏覽器支持:Internet Explorer 10
、Firefox
以及 Opera
支持 animation-play-state
屬性。Safari
和 Chrome
支持替代的 -webkit-animation-play-state
屬性。
註釋:Internet Explorer 9 以及更早的版本不支持 animation-play-state 屬性。html
語法:animation-play-state: paused|running
;
paused 規定動畫已暫停。
running 規定動畫正在播放。web
下面講解一下animation-play-state的使用技巧。
注:示例代碼的私有前綴均省略,你們自行腦補瀏覽器
1. 類名active與動畫觸發
首先,使用active觸發每一屏的動畫,幾乎已經約定俗成,應該也建議成爲默認的行業規範。
通常作法是,當對應一屏內容進入的時候,使用JS給容器添加類名active:佈局
container.classList.add("active");
若是你作的動畫逼格較高,但願每次瀏覽這一屏內容的時候,動畫都走一遍,可使用reflow從新觸發一下animation:動畫
container.classList.remove("active"); container.offsetWidth = container.offsetWidth; container.classList.add("active");
2. 類名active與動畫控制技巧
如何具體控制動畫的播放呢?咱們一般第一反應是使用下面的方法實現,動畫的完整CSS代碼在active狀態下呈現,如:spa
.element1 { /* 尺寸與定位 */ } .element2 { /* 尺寸與定位 */ } .element3 { /* 尺寸與定位 */ } ... .active .element1 { animate: name1 1s; } .active .element2 { animate: name2 1s; } .active .element3 { animate: name2 1s; } ...
從實現和功能上將,上面方法是很不錯的,通俗易懂,不易犯錯。不過我我的更喜歡使用配合CSS3的animation-play-state
屬性對每屏動畫進行控制,實現以下:線程
動畫相關CSS代碼直接寫在元素上:設計
.element1 { /* 尺寸與定位 */ animate: name1 1s; } .element2 { /* 尺寸與定位 */ animate: name2 1s; } .element3 { /* 尺寸與定位 */ animate: name3 1s; } ...
建立一個類名,如.animate,凡是使用到了animation動畫的元素都添加這個類名;
以下CSS代碼:3d
.animate { animation-play-state: paused; } .active .animate { animation-play-state: running; }
之因此我的更喜歡後面的方法,是由於有一種「無侵入」的感受,代碼層次清晰,控制關係明確。有利於後期的維護與擴展。
然而,使用animation-play-state仍是有些須要注意的,對於IE10/IE11瀏覽器,animation-play-state是不能簡寫的。如:
.element { animate: shake 4s 2s both infinite paused; }
只會讓整個CSS聲明掛掉的!以下寫法支持:
.element { animate: shake 4s 2s both infinite; animation-play-state: paused; }
有人可能要奇怪了,怎麼忽然IE瀏覽器亂入了?
首先,咱們不能無視主流手機之Windows Phone. 其次,帥氣的翻屏動畫並非移動端專有,桌面端也適用。稍稍用力,桌面移動全適配,何樂而不爲!
有時候,動畫可能不是一波流,分狀態。
例如,咱們的小火箭,先是淡出動畫,而後無限上下懸浮。怎麼實現呢?
關鍵點就是動畫分解與延時。
據我所知,沒辦法只使用一個keyframes關鍵幀聲明就實現這個效果,由於,這裏有動畫狀態的變化:一個只執行一次的動畫和一個無限循環動畫。
怎麼辦?咱們能夠將動畫分解,寫2個animation keyframes動畫關鍵幀描述。
@keyframes fadeIn { /* ... */ } @keyframes float { /* ... */ }
而後,再分別應用這些關鍵幀動畫。如何應用呢?有2個小技巧:
1. 逗號與多animation動畫值
以下:
<div class="element">小火箭</div> .element { animation: fadeIn 1s, float .5s 1s infinite; } /* 我淡出, 須要1秒;我1秒後開始無限漂浮 */
其中float .5s 1s infinite這裏的1s就是無限漂浮動畫執行延遲的時間,因而,兩個動畫完美配合,感受就像是一個動畫。實際上,就是一個動畫,全部CSS3 animation動畫走同一個UI線程,這也是爲什麼推薦使用CSS實現動畫效果的緣由。
此寫法沒有兼容性問題,你們能夠開開心心地使用。
2. 標籤嵌套與獨立動畫
咱們還能夠經過嵌套標籤的形式實現連續動畫,例如:
<div class="element-wrap"><div class="element">小火箭</div></div> .element-wrap { animation: fadeIn 1s; } /* 我淡出, 須要1秒 */ .element { animation: float .5s 1s infinite; } /* 我1秒後開始無限漂浮 */
有人可能會奇怪了。animation自己就支持多動畫並行,你還搞個標籤嵌套,沒有任何使用的理由啊!沒錯,單純看咱們這個例子,確實是這樣。可是:
① 提取公用動畫
這類多屏動畫是有N多元素同時執行不一樣的動畫。比方說,火箭是淡出,而後上下漂浮;火箭的火焰是淡出,而後大小變化;黑洞是淡出,而後左右隨波。你如何實現?
若是純粹藉助animation語法,應該是:
.element1 { animation: fadeIn 1s, float .5s 1s infinite; } /* 我淡出, 須要1秒;我1秒後開始無限漂浮 */ .element2 { animation: fadeIn 1s, size .5s 1s infinite; } /* 我淡出, 須要1秒;我1秒後開始大小變化 */ .element3 { animation: fadeIn 1s, move .5s 1s infinite; } /* 我淡出, 須要1秒;我1秒後開始左右移動 */
能夠看到,淡出是公用的動畫效果,咱們能夠藉助嵌套標籤,實現公用語法的合併,方面後期維護:
.element-wrap { animation: fadeIn 1s; } /* 你們都1秒淡出 */ .element1 { animation: float .5s 1s infinite; } /* 我1秒後無限漂浮 */ .element2 { animation: size .5s 1s infinite; } /* 我1秒後忽大忽小 */ .element3 { animation: move .5s 1s infinite; } /* 我1秒後左右移動 */
②避免變換衝突
有個元素動畫是邊360度旋轉、邊放大(從0放大到100%),像這種具備典型特徵的動畫咱們顯然要獨立提取與公用的:
@keyframes spin { /* transform: rotate... */ } @keyframes zoomIn { /* transform: scale... */ }
好了,如今問題來了,變放大邊旋轉:
.element { animation: spin 1s, zoomIn 1s; } /* 旋轉:啊,完蛋啦,我被放大覆蓋啦! */
因爲都是使用transform, 發生了殘忍的覆蓋。固然,有好事的人會說,你使用zoom不就行了!確實,若是隻是移動端,使用zoom確實棒棒噠!可是,咱們這個企業活動,PC是主戰場,所以,FireFox瀏覽器(FF不識zoom)是不能無視的。
怎麼辦?從新建一個名爲spinZoomIn的動畫關鍵幀描述仍是?
對啊,你直接外面套一層標籤不就萬事大吉了
.element-wrap { animation: spin 1s; } /* 我轉轉轉 */ .element { animation: zoomIn 1s; } /* 我大大大 */
①. 不使用keyframes決定初始位置
應該都知道,CSS3 animation的fill-mode能夠決定元素動畫結束先後的位置,也就是也具備定位的做用。此時,可能就會有小夥伴,故做聰明,利用animation keyframes 0% {}或form {}去作定位,貌似,還省了寫代碼。看上去很贊,實際上狹隘了,這對於對animation支持不佳或不支持的瀏覽器其實是不友好的,例如Android2.3不支持animation-fill-mode, IE6-IE9不支持CSS3 animation,因而乎,當遭遇這些瀏覽器的時候,頁面動畫元素的佈局其實是毀掉的。因此,這些動畫元素定位的時候,須要使用「無侵入定位」,也就是,就算頁面沒有animation, 我也是個「標緻人兒」。
②. 不使用keyframes中出現的屬性定位
舉個例子,有個球,正好定位在模塊的中心,同時有個無限旋轉效果。使用transform: translate(-50%,-50%)居中定位再合適不過了,不用我內心難受,因而,使用了transform定位。此時,衝突發生,旋轉動畫也是須要transform變換的。
@keyframes spin { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } }
要麼使用業界約定俗成spin覆蓋,要麼另起爐竈無法重用:
@keyframes spin-trans { 0% { transform: rotate(0) translate(-50%,-50%); } 100% { transform: rotate(360deg) translate(-50%,-50%); } }
顯然,都是不合適的。建議使用傳統left/top/margin進行定位,與transform變換動畫「無侵入」。
①. 元素定位在容器中間
容器以及容器內的動畫元素能夠當作是一個動畫模塊,爲了這個模塊能夠輕鬆駕馭水平佈局和垂直局部,裏面的動畫元素造成的總體必定要在容器的中間,不要被設計稿或周圍環境影響。
②. 定位方式爲居中定位
所謂「居中定位」是相對「傳統定位」而言的。Web頁面中的模塊、文字什麼的默認都是相對於左上角堆砌的,因此,很天然地,咱們在重構頁面,作佈局,寫交互效果的時候,也都是相對左上角定位。活用元素自己的定位特性,這是很讚的也推薦這麼作!可是,若是你和多元素CSS動畫打交道,可能就須要改變下慣性思惟了,很重要的一點就是「從以左上角爲參考點變成以中心點爲參考點」
。
咱們在實現多元素動畫效果時候,會出現兩類角色:一是容器;二是容器裏面諸多動畫元素。
其中,對於容器元素,尤爲在作移動端產品時候,咱們很天然會讓其居中定位:
.container { position: absolute; left: 50%; top: 50%; transform: translate3d(-50%, -50%, 0); }
左上角定位(或右上角定位):
.example { position: absolute; left: 100px; top: 100px; }
心點定位+ margin偏移:
.example { position: absolute; left: 50%; top: 50%; margin-left: -100px; margin-top: -100px; }