在《CSS魔法堂:Transition就這麼好玩》中咱們瞭解到對於簡單的補間動畫,咱們能夠經過transition
實現。那到底多簡單的動畫適合用transtion
來實現呢?答案就是——咱們只需定義動畫起始和結束幀的狀態的動畫。一旦關鍵幀數大於2時,咱們必須轉向CSS Animation了。本文爲這段時間學習的記錄,歡迎拍磚。css
語法:html
@keyframes <Animation Name> { [<Animation Time Offset> { /* CSS Properties */ }]* }
示例:css3
@keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
注意項:
1.<Animation Name>
的命名規範wordpress
// 命名須要遵循如下規則 const rIsInvalid = /^--|^[0-9]+-|^(?:unset|initial|inherit|none)$/ , rIsValid = /^[0-9a-z-_\\]+$/i function isValidAnimationName(animationName: string): boolean{ return !rIsInvalid.test(animationName) && rIsValid(animationName) }
2.<Animation Time Offset>
取值0-100%
、from
,等價與0%
、 to
,等價與100%
。
3.<Animation Name>
重複怎麼辦
@keyframes CSS規則不支持層疊樣式,所以當出現多個同名keyframes,那麼僅最後出現的那個有效。函數
/* 無效 */ @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* 生效 */ @keyframes rotate { from { transform: rotate(90deg); } to { transform: rotate(-360deg); } }
4.<Animation Time Offset>
重複怎麼辦
與@keyframes CSS規則同樣,標準規定相同的關鍵幀不產生層疊,僅最後出現的認定爲有效。
但實際上FireFox14+和Chrome均將關鍵幀設計爲可層疊的。學習
@keyframes rotate { from { transform: rotate(0deg); } from { background: red; } /* 上述兩條time offset實際上等價於 * from { transform: rotate(0deg); background: red; } */ to { transform: rotate(360deg); background: yellow; } }
5.!important
致使屬性失效
通常狀況下使用!important
會讓CSS屬性得到最高權重,但在@keyframes下卻會致使該CSS屬性失效。動畫
@keyframes rotate { from { transform: rotate(90deg); background: red!important; /* background屬性無效 */ } to { transform: rotate(-360deg); } }
6.必須提供至少兩個關鍵幀spa
/* 不會根據緩動函數產生動畫效果,而是在動畫持續時間的最後瞬間移動過去 */ @keyframes move-left{ to { left: 100px; } }
<css-selector> { animation: <animation-name> <animation-duration> <animation-timing-function> <animation-delay> <animation-iteration-count> <animation-direction> <animation-fill-mode> <animation-play-state>; }
示例:.net
.box.rotate { animation: rotate 10s infinite alternate; }
<animation-name>
,指定經過@keyframes定義的補間動畫名稱。<animation-duration>
,動畫持續時長,默認爲0s。單位爲s和ms。<animation-delay>
,動畫播放延遲,默認爲0s。單位爲s和ms。<animation-iteration-count>
,動畫重複播放次數,默認爲1,infinite表示無限循環。動畫播放總時長爲<animation-duration>*<animation-iteration-count>
。<animation-direction>
,可選值爲normal | reverse | alternate | alternate-reverse
,分別表示動畫播放順序是從from到to
,從to到from
,從from到to再從to到from
和從to到from再從from到to
。注意:設置alternate|alternate-reverse時,animation-iteration-count必須大於1才能看到效果<animation-fill-mode>
,可選值爲none | forwards | backwards | both
,用於設置動畫開始前和結束後是否應用0%
和100%
的樣式對元素上。分別表示不該用
,應用100%的樣式
,延遲播放期間應用0%的樣式
和0%和100%的樣式均應用
。
注意:設計
<animation-play-state>
,可選值running | paused
,獲取和設置播放狀態。注意:經過這個屬性,咱們僅能實現暫停和繼續播放的效果,沒法實現重播,更別說回放了<animation-timing-function>
,用於設置緩動函數類型,值爲ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end | steps(<integer>, <flag>) | frames(<integer>) | cubic-bezier(<number>,<number>,<number>,<number>)
。
其中ease | ease-in | ease-out | ease-in-out | linear | cubic-bezier(<number>,<number>,<number>,<number>)
的效果均爲連續漸變的,而step-start | step-end | steps(<integer>, <flag>) | frames(<integer>)
則爲突變效果。下面咱們深刻理解後者吧。
step
解疑專題 step-start
實際上等價於steps(10, start)
,而step-end
則等價於steps(10)
,因此咱們只要理解好steps(<integer>, <flag>)
便可。
/* 經過設置在一個動畫週期內(<animation-duration>)的平均刷新幀數,實現突變更效。具體應用有:遊戲精靈行走、打字效果等 * <number_of_steps> - 兩個關鍵幀間的刷新次數 * <direction> - 方向,可選值爲 end | start。 * end爲默認值,表示動畫一結束,動畫效果就結束; * start表示動畫一開始就立刻執行完第一個關鍵幀的效果。 */ steps(<number_of_steps>, <direction>)
從張旭鑫那偷來的解釋:
start:表示直接開始。也就是時間纔開始,就已經執行了一個距離段。因而,動畫執行的5個分段點是下面這5個,起始點被忽略,由於時間一開始直接就到了第二個點:
end:表示戛然而止。也就是時間一結束,當前距離位移就中止。因而,動畫執行的5個分段點是下面這5個,結束點被忽略,由於等要執行結束點的時候已經沒時間了:
另外經過將<animation-fill-mode>
設置爲forwards
,那麼當<direciton>
設置爲end時,也會顯示(保持)動畫最後一個關鍵幀的樣式。
const target = document.getElementById("target") target.addEventListener("animationstart", e => { // 動畫開始時觸發 }) target.addEventListener("animationiteration", e => { // 每次重複執行動畫時觸發 // 當<animation-iteration-count>爲1時,不會觸發。 }) target.addEventListener("animationend", e => { // 當動畫結束時觸發 })
到這裏咱們已經能夠經過@keyframes
定義和應用CSS Animation了,但咱們可否獲取對動畫效果更多的控制權呢?如開始、暫停、繼續、重播。經過<animation-play-state>
咱們能輕易實現開始、暫停和繼續的效果,但重播卻沒那麼容易。
function pause (target: HTMLElement):boolean { const isRunning = target.style.animationPlayState == "running" if (isRunning) { target.style.animationPlayState = "paused" } return isRunning } function play (target: HTMLElement):boolean { const isStop = target.style.animationPlayState == "paused" if (isStop) { target.style.animationPlayState = "running" } return isStop } function replay (target: HTMLElement, animationClassName: string):void { // 先移除動畫效果 target.classList.remove(animationName) // requestAnimationFrame的回調函數會在下一次界面渲染前執行 requestAnimationFrame(_ => { // 這時動畫的影響還在,因此要等界面渲染完後再從新啓用動畫效果,才能實現重播 requestAnimationFrame(_ => { target.classList.add(animationName) }) }) }
CSS3爲咱們提供了動畫效果,除了提供比Transition更豐富的可控性,比JavaScript更簡易的API,還讓咱們能夠使用GPU來加速呢^_^
尊重原創,轉載請註明來自:https://www.cnblogs.com/fsjoh... ^_^肥仔John
https://developer.mozilla.org...
https://designmodo.com/steps-...
http://lea.verou.me/2011/09/p...
http://jsfiddle.net/simurai/C...
https://www.zhangxinxu.com/wo...