animation 動畫
animation
是動畫,而 transition
是過渡,它們用法很相似,但實際又不大相同,可以說 animation
是 transition
的升級版,它可以創(chuàng)建一個持續(xù)的自動執(zhí)行動畫。
1. 官方定義
animation
屬性是一個簡寫屬性,它是下面屬性的縮寫:
animation-name
animation-duration
animation-timing-function
animation-delay
animation-iteration-count
animation-direction
animation-fill-mode
注意:請始終規(guī)定 animation-duration
屬性,否則時長為 0,就不會播放動畫了。
2. 慕課解釋
animation
是幾個屬性值的縮寫,我們定義一個動畫通常使用 animation
就足夠了,如果想單獨改變動畫的某些屬性可以使用單獨的動畫屬性去改變,構(gòu)成一個動畫的最基本屬性需要 一個@keyframes
和 duration
。
3. 語法
.demo{
animation: name duration timing-function delay iteration-count direction;
}
屬性值說明:
屬性 | 描述 |
---|---|
animation-name | 規(guī)定需要綁定到選擇器的 keyframe 名稱。 |
animation-duration | 規(guī)定完成動畫所花費的時間,以秒或毫秒計。 |
animation-timing-function | 規(guī)定動畫的速度曲線。 |
animation-delay | 規(guī)定在動畫開始之前的延遲。以秒或毫秒計。 |
animation-iteration-count | 規(guī)定動畫應(yīng)該播放的次數(shù)。 一個整數(shù)代表重復(fù)的次數(shù)或者 infinite 無限重復(fù) |
animation-direction | 規(guī)定是否應(yīng)該輪流反向播放動畫。 |
animation-direction 參數(shù)值詳解:
值 | 描述 |
---|---|
normal | 默認值。動畫按正常播放。 |
reverse | 動畫反向播放。 |
alternate | 動畫在奇數(shù)次(1、3、5…)正向播放,在偶數(shù)次(2、4、6…)反向播放。 |
alternate-reverse | 動畫在奇數(shù)次(1、3、5…)反向播放,在偶數(shù)次(2、4、6…)正向播放。 |
initial | 設(shè)置該屬性為它的默認值。 |
inherit | 從父元素繼承該屬性。 |
animation-fill-mode
參數(shù)值詳解
值 | 描述 |
---|---|
none | 默認值。動畫在動畫執(zhí)行之前和之后不會應(yīng)用任何樣式到目標元素。 |
forwards | 設(shè)置動畫結(jié)束之后使用結(jié)束后的狀態(tài)作為樣式。 |
backwards | 在設(shè)置延遲之后 元素使用動畫設(shè)置的開始的狀態(tài) |
both | 在設(shè)置動畫延遲情況下,元素使用開始的狀態(tài),并在整個動畫結(jié)束之后使用結(jié)束之后的狀態(tài)。 |
initial | 設(shè)置該屬性為它的默認值。 |
inherit | 從父元素繼承該屬性。 |
4. 兼容性
IE | Edge | Firefox | Chrome | Safari | Opera | ios | android |
---|---|---|---|---|---|---|---|
9+ | 12+ | 28+ | 4+ | 6.1+ | 12.1+ | 7+ | 4.4 |
5. 實例
- 使用
from to
定義一個名字為go
的@keyframes
的動畫。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ;
}
效果圖
說明:這是最簡單的動畫創(chuàng)建方式,使用 @keyframes 命名一個叫做 go 的動畫,再為這個動畫加上一個 2s 的持續(xù)時間 ,構(gòu)成了最簡單的動畫,但是它只播放一次。
- 對上面的例子進行改造,通過設(shè)置動畫函數(shù),修改動畫執(zhí)行的快慢。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in;/*這里增加了動畫函數(shù)*/
}
效果圖
說明:通過在 animation 增加第 3 個參數(shù) animation-timing-function 動畫函數(shù),它可以改變動畫運動的速度曲線。
Tips:要注意的是,不管怎么改變動畫的結(jié)束時間是不會變的。具體可以看 timing-function 的介紹。
- 繼續(xù)對上面例子增加一個延遲實現(xiàn) 3s 后在執(zhí)行動畫。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 3s;/*這里增加了動畫延遲時間 3 秒*/
}
效果圖
說明:動畫延遲了 3 秒開始再次執(zhí)行了。
- 增加 animation-iteration-count 屬性,改變動畫的播放次數(shù)。
動畫延遲 3s 開始播放,播放 2 次結(jié)束。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 3s 2;/*播放 2 次結(jié)束*/
}
效果圖
說明:通過效果圖可以很清楚的看到了動畫反復(fù)執(zhí)行了 2 次,值得注意的這個 3s 的延遲只針對第一次動畫開始前,在動畫開始之后重復(fù)循環(huán)的時候就不再起作用了。
動畫延遲 3s 開始播放,然后無限循環(huán)。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 3s infinite;/*無限次循環(huán)*/
}
效果圖
說明:通過 infinite
動畫在經(jīng)過 3s
的延遲之后開始無限的循環(huán)了。
animation-direction
來改變動畫在循環(huán)過程中是否反向。
延續(xù)上面的例子,我們發(fā)現(xiàn)動畫每次循環(huán)都是從開始的位置開始循環(huán)的,下面通過添加 animation-direction
來改變動畫在循環(huán)過程中是否反向。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 3s infinite reverse;/*動畫反向播放*/
}
使用 alternate
屬性,讓動畫在奇數(shù)時候正向播放,偶數(shù)時候反向播放。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 3s infinite alternate;
}
效果圖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 3s infinite;/*動畫反向播放*/
}
.demo-1{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 3s infinite reverse;/*動畫反向播放*/
}
.demo-2{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 3s infinite alternate;/*動畫偶數(shù)反向播放*/
}
</style>
</head>
<body>
<h2>正常播放順序</h2>
<div class="demo"></div>
<h2>反向播放順序</h2>
<div class="demo-1"></div>
<h2>奇數(shù)正向播放偶數(shù)次反向播放</h2>
<div class="demo-2"></div>
</body>
</html>
animation-fill-mode
設(shè)置動畫的初始或結(jié)束狀態(tài)。
單次動畫使用 forwards
設(shè)置動畫結(jié)束之后使用結(jié)束后的狀態(tài)作為樣式。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 1s forwards;
}
在設(shè)置延遲之后元素中使用 backwards
設(shè)置動畫的開始的樣式。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 1s backwards;
}
效果圖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 2s ;/*動畫反向播放*/
}
.demo-1{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 2s forwards;
}
.demo-2{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 2s backwards;
}
</style>
</head>
<body>
<h2>正常動畫</h2>
<div class="demo"></div>
<h2>設(shè)置 forwards</h2>
<div class="demo-1"></div>
<h2>設(shè)置 backwards 注意觀察開始</h2>
<div class="demo-2"></div>
</body>
</html>
說明:在鼠標刷新瀏覽器我們看到本應(yīng)該 100px 寬度的元素是以 200px 開始的,當動畫結(jié)束之后,回到了 100px。
both
在設(shè)置動畫延遲情況下,元素使用開始的狀態(tài),并在整個動畫結(jié)束之后使用結(jié)束之后的狀態(tài)。
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 2s both;
}
效果圖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
@keyframes go{
from{
width:200px;
}
to{
width:500px
}
}
.demo{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 2s ;/*動畫反向播放*/
}
.demo-3{
width:100px;
height:100px;
background: #000;
animation:go 2s ease-in 2s both;
}
</style>
</head>
<body>
<h2>正常動畫</h2>
<div class="demo"></div>
<h2>設(shè)置 both 注意觀察開始和結(jié)束</h2>
<div class="demo-3"></div>
</body>
</html>
6. 經(jīng)驗分享
-
當動畫造成頁面的卡頓,可以用下面這種方式嘗試解決:
開啟 GPU 加速,例如使用transform:transition3d(0,0,0)
。 -
有時候需要實現(xiàn)鼠標
hover
到元素上,會出現(xiàn)一個提示效果。如果使用transition
過渡屬性發(fā)現(xiàn)總是不能實現(xiàn)這個效果,而animation
是可以解決的:
<div class="demo">
往事不要再提<span>人生已多風雨</span>
</div>
.demo{
cursor: pointer;
}
.demo>span{
display: none;
}
.demo:hover>span{
display: block;
animation: shows 1s forwards;
}
@keyframes shows {
from{
opacity: 0;
}to{
opacity: 1;
}
}
效果圖
說明: transition
不能實現(xiàn)(隱藏/顯示)之間的過渡效,原因是 diaplay:none
設(shè)置之后雖然元素在頁面中,但是這個標簽不在瀏覽器的渲染進程里面。如果這個元素屬性為 display:block
相當于元素從新渲染出來,這時里面的 opacity: 0
到 1 就不起作用了。所以這里使用 animation
正好可以彌補這個問題。
7. 小結(jié)
- 盡量停止不可以見的動畫,以減少卡頓。
- 盡量使用
transform
屬性完成動畫內(nèi)部屬性的切換,因為它是使用 GPU 計算的,也會提升動畫的性能。