× 目錄 [1]定義 [2]關鍵幀 [3]動畫屬性 [4]多值 [5]API 前面的話 transition過渡是通過初始和結束兩個狀態之間的平滑過渡實現簡單動畫的;而animation則是通過關鍵幀@keyframes來實現更為複雜的動畫效果。本文將介紹關於animation動畫的相關知識 定義 ...
×
目錄
[1]定義 [2]關鍵幀 [3]動畫屬性 [4]多值 [5]API前面的話
transition過渡是通過初始和結束兩個狀態之間的平滑過渡實現簡單動畫的;而animation則是通過關鍵幀@keyframes來實現更為複雜的動畫效果。本文將介紹關於animation動畫的相關知識
定義
和transition類似,animation也是一個複合屬性,包括animation-name、animation-duration、animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-play-state、animation-fill-mode共8個子屬性
[註意]IE9-不支持;safari4-8、IOS3.2-8.4、android2.1-4.4.4需要添加-webkit-首碼
animation-name: 動畫名稱(預設值為none) animation-duration: 持續時間(預設值為0) animation-timing-function: 時間函數(預設值為ease) animation-delay: 延遲時間(預設值為0) animation-iteration-count: 迴圈次數(預設值為1) animation-direction: 動畫方向(預設值為normal) animation-play-state: 播放狀態(預設值為running) animation-fill-mode: 填充模式(預設值為none)
div{ width: 300px; height: 100px; background-color: pink; animation-name: test; animation-duration: 3s; animation-timing-function: ease; animation-delay: 0s; animation-iteration-count: infinite; animation-direction: normal; animation-play-state: running; animation-fill-mode: none; } /* 關於keyframes關鍵幀的內容稍後介紹 */ @keyframes test{ 0%{background-color: lightblue;} 30%{background-color: lightgreen;} 60%{background-color: lightgray;} 100%{background-color: black;} }
關鍵幀
animation製作動畫效果需要兩步,首先用關鍵幀聲明動畫,再用animation調用動畫
關鍵幀的語法是以@keyframes開頭,後面緊跟著動畫名稱animation-name。from等同於0%,to等同於100%。百分比跟隨的花括弧裡面的代碼,代表此時對應的樣式
@keyframes animation-name{ from | 0%{} n%{} to | 100%{} }
【1】百分比順序不一定非要從0%到100%排列,最終瀏覽器會自動按照0%-100%的順序進行解析
[註意]0%不可以省略百分號
@keyframes test{ 100%{background-color: black;} 60%{background-color: lightgray;} 30%{background-color: lightgreen;} 0%{background-color: lightblue;} }
div{ width: 300px; height: 100px; background-color: pink; animation-name: test; animation-duration: 3s; animation-iteration-count: infinite; }
【2】如果存在負百分數或高於100%的百分數,則該關鍵幀將被忽略
/* -20%和120%對應的代碼無效*/ @keyframes test{ -20%{background-color: red;} 0%{background-color: lightblue;} 30%{background-color: lightgreen;} 60%{background-color: lightgray;} 100%{background-color: black;} 120%{background-color: yellow;} }
【3】如果0%或100%不指定關鍵幀,將使用該元素預設的屬性值
/* 0%和100%對應的顏色是預設值pink*/ @keyframes test{ 30%{background-color: lightgreen;} 60%{background-color: lightgray;} }
【4】若存在多個@keyframes,瀏覽器只識別最後一個@keyframes裡面的值
/* 後面覆蓋前面 */ @keyframes test{ 0%{background-color: lightblue;} 30%{background-color: lightgreen;} 60%{background-color: lightgray;} 100%{background-color: black;} } @keyframes test{ 0%{background-color: blue;} 30%{background-color: green;} 60%{background-color: gray;} 100%{background-color: black;} }
【5】空的keyframes規則是有效的,它們會覆蓋前面有效的關鍵幀規則
/* 後面覆蓋前面 */ @keyframes test{ 0%{background-color: lightblue;} 30%{background-color: lightgreen;} 60%{background-color: lightgray;} 100%{background-color: black;} } @keyframes test{ }
動畫屬性
動畫名稱
animation-name
值: none | <single-animation-name> [, <single-animation-name> ]*
初始值: none
應用於: 所有元素
繼承性: 無
<single-animation-name>: none | 自定義動畫名稱
【1】如果多個動畫試圖修改相同的屬性,那麼動畫列表的後面覆蓋前面
/* animation-name的順序是test1,test2,且它們修改的是同樣的屬性,後面覆蓋前面,所以test2有效,test1無效 */ div{ width: 300px; height: 100px; background-color: pink; animation-name: test1,test2; animation-duration: 3s; animation-iteration-count: infinite; } @keyframes test2{ 0%{background-color: blue;} 30%{background-color: green;} 60%{background-color: gray;} 100%{background-color: black;} } @keyframes test1{ 0%{background-color: lightblue;} 30%{background-color: lightgreen;} 60%{background-color: lightgray;} 100%{background-color: black;} }
【2】如果動畫的其他7個子屬性和動畫名稱的長度不同,動畫名稱列表的長度決定最終的長度,多餘的值無餘,缺少的值按照順序進行重覆
div{ width: 300px; height: 100px; position: relative; background-color: pink; animation-name: test1,test2,test3; animation-duration: 3s,1s; animation-iteration-count: infinite; } @keyframes test1{ 0%{background-color: lightblue;} 30%{background-color: lightgreen;} 60%{background-color: lightgray;} 100%{background-color: black;} } @keyframes test2{ 0%{font-size: 20px;} 30%{font-size: 30px;} 60%{font-size: 40px;} 100%{font-size: 50px;} } @keyframes test3{ 0%{left: 0px;} 30%{left: 30px;} 60%{left: 40px;} 100%{left: 50px;} }
<div>測試文字</div>
持續時間
持續時間指完成動畫的時間
animation-duration
值: <time> [, <time>]*
初始值: 0s
應用於: 所有元素
繼承性: 無
animation-duration: <time>[,<time>]*
0s意味著動畫沒有時間,持續時間不能為負值
animation-name: test1,test2; <!-- test1的持續時間設置為負值,將使得整個動畫持續時間都失效,因此test2也將沒有動畫效果 --> animation-duration: -1s,1s;
時間函數
animation-timing-function
值: <single-timing-function> [, <single-timing-function>]*
初始值: ease
應用於: 所有元素
繼承性: 無
animation的時間函數類似於transition的時間函數。時間函數可以應用於整個動畫中,也可以應用於關鍵幀的某兩個百分比之間
div{ width: 300px; height: 100px; position: relative; background-color: pink; animation-name: test; animation-duration: 5s; animation-iteration-count: infinite; } @keyframes test{ 0%{left: 0px;animation-timing-function: ease;} 20%{left: 50px;animation-timing-function: linear;} 40%{left: 100px;animation-timing-function: ease-in;} 60%{left: 150px;animation-timing-function: ease-out;} 80%{left: 200px;animation-timing-function: step-start;} 100%{left: 250px;animation-timing-function: step-end;} }
迴圈次數
animation-iteration-count
值: infinite | <number>[,infinite | <number>]*
初始值: 1
應用於: 所有元素
繼承性: 無
預設為1,可以是整數也可以小數,但不能是0和負數。如果為infinite則表示無限次動畫
動畫方向
動畫方向用來定義是否動畫需要反向播放
animation-direction
值: <single-animation-direction>[,<single-animation-direction> ]*
初始值: normal
應用於: 所有元素
繼承性: 無
<single-animation-direction> = normal | reverse | alternate | alternate-reverse
normal: 正向播放
reverse: 反向播放
alternate: 若動畫只播放一次,則和正向播放一樣。若播放兩次以上,偶數次效果為反向播放
alternate-reverse: 若動畫只播放一次,則和反向播放一樣。若播放兩次以上,偶數次效果為正向播放
[註意]safari瀏覽器不支持reverse屬性和alternate-reverse屬性
動畫狀態
animation-play-state
值:running | paused[,running | paused]*
初始值: running
應用於: 所有元素
繼承性: 無
running表示播放中,paused表示動畫暫停
延遲時間
定義延遲多少時間後動畫開始播放
animation-delay
值: <single-animation-delay>[,<single-animation-delay> ]*
初始值: 0s
應用於: 所有元素
繼承性: 無
<single-animation-delay>= <time>[,<time>]*
如果該值是負值,則表示動畫的起始時間從0s變為延遲時間的絕對值。
填充模式
定義動畫開始幀之前和結束幀之後的動作
[註意]android2.1-3不支持animation-fill-mode
animation-fill-mode
值: <single-animation-fill-mode>[,<single-animation-fill-mode> ]*
初始值: none
應用於: 所有元素
繼承性: 無
<single-animation-fill-mode> = none | forwards | backwards | both
none: 動畫結束後,元素移動到初始狀態 [註意]初始狀態並不是指0%的元素狀態,而是元素本身屬性值 forwards: 元素停在動畫結束時的位置 [註意]動畫結束時的位置並不一定是100%定義的位置,因為動畫有可能反向運動,也有可能動畫的次數是小數 backwards:在animation-delay的時間內,元素立刻移動到動畫開始時的位置。若元素無animation-delay時,與none的效果相同 [註意]動畫開始時的位置也不一定是0%定義的位置,因為動畫有可能反向運動。 both: 同時具有forwards和backwards的效果
[註意]當持續時間animation-duration為0s時,animation-fill-mode依然適用,當animation-fill-mode的值為backwards時,動畫填充在任何animation-delay的階段。當animation-fill-mode的值為forwards時,動畫將保留在100%的關鍵幀上
多值
animation
值: <single-animation>[,<single-animation> ]*
初始值: 無
應用於: 所有元素
繼承性: 無
<single-animation> = <single-animation-name> || <single-animation-duration> || <single-animation-timing-function> || <single-animation-delay> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state>
[註意]持續時間在前,延遲時間在後,若只存在一個時間,則是持續時間
div{ width: 300px; height: 100px; background-color: pink; animation: 1s test1,infinite test2 2s 1s; } @keyframes test1{ 30%{background-color: red;} 60%{background-color: blue;} 100%{background-color: green;} } @keyframes test2{ 100%{color: white;} }
API
animation涉及到的事件有animationstart、animationend、animationiteration三個。這三個事件的bubbles都是yes,cancelalbe都是no
[註意]對於safari瀏覽器,animation的事件為webkitAnimationStart、webkitAnimationEnd、webkitAnimationIteration
[註意]動畫事件只支持DOM2級事件處理程式的寫法
animationstart
發生在動畫開始時
【1】如果存在delay,且delay為正值,則元素等待延遲完畢後,再觸發該事件
【2】如果delay為負值,則元素先將初始值變為delay的絕對值時,再觸發該事件
oSb.addEventListener('animationstart',function(){ this.innerHTML = '動畫開始'; this.style.background = 'lightgreen'; },false);
animationend
發生在動畫結束時
test.addEventListener('animationend',function(){ this.style.background="lightgreen"; this.innerHTML = '動畫結束'; },false);
animationiteration
發生在動畫的一次迴圈結束時,只有當iteration-count迴圈次數大於1時,觸發該事件
var i = 0; oSb.addEventListener('animationiteration',function(){ i++; this.innerHTML = i; },false);
【補充】
只有改變animation-name時,才會使animation動畫效果重新觸發
oSb.style.animationName = 'none'; setTimeout(function(){ oSb.style.animationName = 'test'; },100);