W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
CSS 動畫可以在不借助 Javascript 的情況下做出一些簡單的動畫效果。
你也可以通過 Javascript 控制 CSS 動畫,使用少量的代碼,就能讓動畫表現(xiàn)更加出色。
CSS 過渡的理念非常簡單,我們只需要定義某一個屬性以及如何動態(tài)地表現(xiàn)其變化。當屬性變化時,瀏覽器將會繪制出相應(yīng)的過渡動畫。
也就是說:我們只需要改變某個屬性,然后所有流暢的動畫都由瀏覽器生成。
舉個例子,以下 CSS 會為 backgroud-color
的變化生成一個 3 秒的過渡動畫:
.animated {
transition-property: background-color;
transition-duration: 3s;
}
現(xiàn)在,只要一個元素擁有名為 .animated
的類,那么任何背景顏色的變化都會被渲染為 3 秒鐘的動畫。
單擊以下按鈕以演示動畫:
<button id="color">Click me</button>
<style>
#color {
transition-property: background-color;
transition-duration: 3s;
}
</style>
<script>
color.onclick = function() {
this.style.backgroundColor = 'red';
};
</script>
CSS 提供了四個屬性來描述一個過渡:
transition-property
?transition-duration
?transition-timing-function
?transition-delay
?之后我們會詳細介紹它們,目前我們需要知道,我們可以在 transition
中以 property duration timing-function delay
的順序一次性定義它們,并且可以同時為多個屬性設(shè)置過渡動畫。
請看以下例子,點擊按鈕生成 color
和 font-size
的過渡動畫:
<button id="growing">Click me</button>
<style>
#growing {
transition: font-size 3s, color 2s;
}
</style>
<script>
growing.onclick = function() {
this.style.fontSize = '36px';
this.style.color = 'red';
};
</script>
現(xiàn)在讓我們一個一個展開看這些屬性。
在 transition-property
中我們可以列舉要設(shè)置動畫的所有屬性,如:left、margin-left、height 和 color
。
不是所有的 CSS 屬性都可以使用過渡動畫,但是它們中的大多數(shù)都是可以的。all
表示應(yīng)用在所有屬性上。
transition-duration
允許我們指定動畫持續(xù)的時間。時間的格式參照 CSS 時間格式:單位為秒 s
或者毫秒 ms
。
transition-delay
允許我們設(shè)定動畫開始前的延遲時間。例如,對于 transition-delay: 1s
,動畫將會在屬性變化發(fā)生 1 秒后開始渲染。
你也可以提供一個負值。那么動畫將會從整個過渡的中間時刻開始渲染。例如,對于 transition-duration: 2s
,同時把 delay
設(shè)置為 -1s
,那么這個動畫將會持續(xù) 1 秒鐘,并且從正中間開始渲染。
這里演示了數(shù)字從 0
到 9
的動畫,使用了 CSS translate
方法:
如下在 tranform
屬性上應(yīng)用動畫:
#stripe.animate {
transform: translate(-90%);
transition-property: transform;
transition-duration: 9s;
}
在以上的例子中,JavaScript 把 .animate
類添加到了元素上,由此觸發(fā)了動畫:
stripe.classList.add('animate');
我們也可以『從中間』開始,也就是說從某個特定數(shù)字開始,比方說,從當前的時間的秒數(shù)開始。這就要用到負的 transition-delay
。
此處,如果你單擊這個數(shù)字,那么它會從當前的秒數(shù)開始渲染:
只需添加一行 JavaScript 代碼:
stripe.onclick = function() {
let sec = new Date().getSeconds() % 10;
// for instance, -3s here starts the animation from the 3rd second
stripe.style.transitionDelay = '-' + sec + 's';
stripe.classList.add('animate');
};
時間函數(shù)描述了動畫進程在時間上的分布。它是先慢后快還是先快后慢?
乍一看,這可能是最復雜的屬性了,但是稍微花點時間,你就會發(fā)現(xiàn)其實也很簡單。
這個屬性接受兩種值:一個貝塞爾曲線(Bezier curve)或者階躍函數(shù)(steps)。我們先從貝塞爾曲線開始,這也是較為常用的。
時間函數(shù)可以用貝塞爾曲線描述,通過設(shè)置四個滿足以下條件的控制點:
(0,0)
?。(1,1)
?。x
? 必須位于 ?0..1
? 之間,?y
? 可以為任意值。CSS 中設(shè)置一貝塞爾曲線的語法為:cubic-bezier(x2, y2, x3, y3)
。這里我們只需要設(shè)置第二個和第三個值,因為第一個點固定為 (0,0)
,第四個點固定為 (1,1)
。
時間函數(shù)描述了動畫進行的快慢。
x
? 軸表示時間:?0
? —— 開始時刻,?1
? —— ?transition-duration
?的結(jié)束時刻。y
? 軸表示過程的完成度:?0
? —— 屬性的起始值,?1
? —— 屬性的最終值。最簡單的一種情況就是動畫勻速進行,可以通過設(shè)置曲線為 cubic-bezier(0, 0, 1, 1)
來實現(xiàn)。
看上去就像這樣:
…正如我們所見,這就是條直線。隨著時間 x
推移,完成度 y
穩(wěn)步從 0
增長到 1
。
例子中的列車勻速地從左側(cè)移動到右側(cè):
這個里面的 CSS 就是基于剛才那條曲線的:
.train {
left: 0;
transition: left 5s cubic-bezier(0, 0, 1, 1);
/* JavaScript sets left to 450px */
}
…那么,我們?nèi)绻憩F(xiàn)出減速行駛的列車呢?
我們可以使用另一條貝塞爾曲線:cubic-bezier(0.0, 0.5, 0.5 ,1.0)
。
圖像如下:
正如我們所見,這個過程起初很快:曲線開始迅速升高,然后越來越慢。
這是實際的效果演示:
CSS:
.train {
left: 0;
transition: left 5s cubic-bezier(0, .5, .5, 1);
/* JavaScript sets left to 450px */
}
CSS 提供幾條內(nèi)建的曲線:linear
、ease
、ease-in
、ease-out
和 ease-in-out
。
linear
其實就是 cubic-bezier(0, 0, 1, 1)
的簡寫 —— 一條直線,剛剛我們已經(jīng)看過了。
其它的名稱是以下貝塞爾曲線的簡寫:
ease *
|
ease-in
|
ease-out
|
ease-in-out
|
---|---|---|---|
(0.25, 0.1, 0.25, 1.0)
|
(0.42, 0, 1.0, 1.0)
|
(0, 0, 0.58, 1.0)
|
(0.42, 0, 0.58, 1.0)
|
*
—— 默認值,如果沒有指定時間函數(shù),那么將使用 ease
作為默認值。
所以,我們可以使用 ease-out
來表現(xiàn)減速行駛的列車:
.train {
left: 0;
transition: left 5s ease-out;
/* transition: left 5s cubic-bezier(0, .5, .5, 1); */
}
但是這看起來有點怪怪的。
貝塞爾曲線可以使動畫『超出』其原本的范圍。
曲線上的控制點的 y
值可以使任意的:不管是負值還是一個很大的值。如此,貝塞爾曲線就會變得很低或者很高,讓動畫超出其正常的范圍。
在一下的例子中使用的代碼:
.train {
left: 100px;
transition: left 5s cubic-bezier(.5, -1, .5, 2);
/* JavaScript sets left to 400px */
}
left
本該在 100px
到 400px
之間變化。
但是如果你點擊列車,你會發(fā)現(xiàn):
left
? 會變得小于 ?100px
?。400px
?。400px
?。為什么會這樣?看一眼給定的貝塞爾曲線的圖像你就會明白了。
我們把第二個點的 y
坐標移動到了小于 0
的位置,同時把第三個點的 y
坐標移動到了大于 1
的位置,因此曲線已經(jīng)不再像一個四分之一圓了。y
坐標超出了常規(guī)的 0..1
的范圍。
正如我們所知,y
表示『動畫進程的完成度』。y = 0
表示屬性的初始值,y = 1
則表示屬性的最終值。因此,y < 0
意味著屬性值要比初始值小,而 y > 1
則表明屬性值要比最終值大。
當然了,-1
和 2
還是比較緩和的值。如果我們把 y
設(shè)為 -99
和 99
,那么列車將會偏離地更遠。
但是,如何針對特定的任務(wù)尋找到合適的貝塞爾曲線呢?事實上,有很多工具可以幫到你。比方說,我們可以利用這個網(wǎng)站:http://cubic-bezier.com/。
時間函數(shù) steps(number of steps[, start/end])
允許你讓動畫分段進行,number of steps
表示需要拆分為多少段。
讓我們通過一個數(shù)字的例子來演示一下。我們將會讓數(shù)字以離散的方式變化,而不是以連續(xù)的方式。
為了達到效果,我們把動畫拆分為 9 段:
#stripe.animate {
transform: translate(-90%);
transition: transform 9s steps(9, start);
}
step(9, start)
生效時:
steps
的第一個參數(shù)表示段數(shù)。這個過渡動畫將會被拆分為 9 個部分(每個占 10%)。時間間隔也會以同樣的方式被拆分:9 秒會被分割為多個時長 1 秒的間隔。
第二個參數(shù)可以取 start
或 end
兩者其一。
start
表示在動畫開始時,我們需要立即開始第一段的動畫。
可以觀察到,在動畫過程中:當我們單擊數(shù)字之后,它會立馬變?yōu)?nbsp;1
(即第一段),然后在下一秒開始的時候繼續(xù)變化。
具體的流程如下:
0s
? —— ?-10%
?(在第一秒開始的時候立即變化)1s
? —— ?-20%
?8s
? – ?-80%
?另一個值 end
表示:改變不應(yīng)該在最開始的時候發(fā)生,而是發(fā)生在每一段的最后時刻。
其流程如下:
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: