過(guò)去 WEB 需要實(shí)現(xiàn)交互動(dòng)畫(huà)效果是使用 ??flash?
? 、??javascript?
?、??Gif?
?,近年來(lái)隨著 ??flash?
? 的淘汰,??javascript?
? 和 ??CSS?
? 功能的增強(qiáng),使得現(xiàn)代 WEB 應(yīng)用的交互越來(lái)越豐富。借此總結(jié)一下 CSS 交互動(dòng)畫(huà)實(shí)現(xiàn)的基礎(chǔ),關(guān)鍵的知識(shí)點(diǎn)是 ??keyframes?
? ,文章涉及的代碼示例效果可以點(diǎn)擊查看????動(dòng)畫(huà)效果。
語(yǔ)法
??keyframe?
? 動(dòng)畫(huà)的實(shí)現(xiàn)原理跟 ??flash?
? 的實(shí)現(xiàn)方式類(lèi)似,在 CSS 塊之間進(jìn)行關(guān)鍵幀的屬性的更新。下面定義一個(gè) ??keyframe?
? 動(dòng)畫(huà),將元素的水平位置從 ??-100%?
? 平滑地漸變到??0%?
?:
@keyframes slide-in {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0%);
}
}
每個(gè) ??@keyframes?
? 語(yǔ)句都需要一個(gè)名稱(chēng),一般為交互動(dòng)畫(huà)效果名稱(chēng),上面的代碼定了一個(gè)滑入 ??slide-in?
? 的效果名稱(chēng)。
和其它 CSS 一樣,??keyframe?
? 動(dòng)畫(huà)也是可以通用的和可重用的,可以將它們應(yīng)用到特定選擇器的 ??animation?
? 屬性中:
.slide-in {
animation: slide-in 1000ms;
}
上面的代碼定了在 ??1000ms?
? 內(nèi),將 ??translateX?
? 屬性進(jìn)行改變,并且立即執(zhí)行。
可以在同一個(gè)動(dòng)畫(huà)聲明中定義多個(gè)屬性的變化,如下:
.drop-in {
animation: drop-in 1000ms;
}
@keyframes drop-in {
from {
transform: rotate(-30deg) translateY(-100%);
opacity: 0;
}
to {
transform: rotate(0deg) translateY(0%);
opacity: 1;
}
}
動(dòng)畫(huà)效果
動(dòng)畫(huà)效果使用 ??animation-timing-function?
? 屬性,定義 CSS 動(dòng)畫(huà)在每一動(dòng)畫(huà)周期中執(zhí)行的節(jié)奏,既是常說(shuō)的動(dòng)畫(huà)效果,類(lèi)似 ??jquery?
? 中的 ??easing?
? 。
.ease-in-out {
animation-timing-function: ease-in-out;
}
循環(huán)動(dòng)畫(huà)
默認(rèn)情況下,??keyframe?
? 動(dòng)畫(huà)只會(huì)運(yùn)行一次,但可以使用 ??animation-iteration-count?
? 屬性來(lái)控制動(dòng)畫(huà)執(zhí)行次數(shù)。
.for-three {
animation-iteration-count: 3;
}
如果是無(wú)限次將其值設(shè)置為 ??infinite?
? ,有限次就按照具體要求輸入次數(shù)。
.spinner {
animation: spin 1000ms;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes spin {
from {
transform: rotate(0turn);
}
to {
transform: rotate(1turn);
}
}
多步動(dòng)畫(huà)
除了 ??from?
? 和 ??to?
? 關(guān)鍵字,還可以使用百分比,可以定義兩個(gè)及以上的動(dòng)畫(huà)步驟:
.fancy-spinner {
animation: fancy-spin 2000ms;
animation-iteration-count: infinite;
}
@keyframes fancy-spin {
0% {
transform: rotate(0turn) scale(1);
}
25% {
transform: rotate(1turn) scale(1);
}
50% {
transform: rotate(1turn) scale(0.5);
}
75% {
transform: rotate(0turn) scale(0.5);
}
100% {
transform: rotate(0turn) scale(1);
}
}
交替動(dòng)畫(huà)
假設(shè)要讓一個(gè)元素“呼吸”,充氣和放氣。 可以將其設(shè)置為 3 步動(dòng)畫(huà):
.grow-shrink {
animation: grow-and-shrink 4000ms;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
@keyframes grow-and-shrink {
0% {
transform: scale(1);
}
50% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}
上面的動(dòng)畫(huà)效果還有一種更優(yōu)雅的方式,使用 ??animation-direction?
? 屬性,用來(lái)指示動(dòng)畫(huà)是否反向播放。
@keyframes grow-and-shrink {
0% {
transform: scale(1);
}
100% {
transform: scale(0.5);
}
}
.grow-shrink {
animation: grow-and-shrink 2000ms;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-direction: alternate;
}
上面定義的動(dòng)畫(huà)都是根據(jù)不同屬性定義不同的值,和其他 CSS 屬性一樣,可以只定義一個(gè)屬性值,即 ?
?animation?
?。
上面定義動(dòng)畫(huà)屬性的方式如下:
animation: grow-and-shrink 2000ms;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-direction: alternate;
更簡(jiǎn)潔的方式,也是推薦使用的方式,跟 ??padding?
? 不一樣的是順序無(wú)關(guān)緊要:
animation: grow-and-shrink 2000ms ease-in-out infinite alternate;
填充模式
??keyframe?
? 動(dòng)畫(huà)令人困惑的方面可能是填充模式,它們是通往??keyframe?
? 信心之路的最大障礙。例如希望元素淡出,動(dòng)畫(huà)本身運(yùn)行良好,但是當(dāng)它結(jié)束時(shí),元素會(huì)重新出現(xiàn)一下導(dǎo)致閃現(xiàn)的效果:
.fade-out {
animation: fade-out 1000ms;
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
為什么元素會(huì)執(zhí)行完動(dòng)畫(huà)后重新再閃現(xiàn)一下并完全可見(jiàn)了,這是因?yàn)???from?
? 和 ??to?
? 塊中的聲明只在動(dòng)畫(huà)運(yùn)行時(shí)有效。
??1000ms?
? 動(dòng)畫(huà)完成過(guò)后,元素就按照CSS聲明顯示,而透明度默認(rèn)情況下是不透明的。因此動(dòng)畫(huà)完成后透明度又恢復(fù)到不透明了。
解決這個(gè)問(wèn)題的一種方法是在動(dòng)畫(huà)之外聲明透明度,如下:
.fade-out-2 {
animation: fade-out 1000ms;
opacity: 0;
}
上面的方案雖然解決了問(wèn)題,但這不是最佳的方式。最佳的方式是使用屬性 ??animation-fill-mode?
? ,設(shè)置CSS動(dòng)畫(huà)在執(zhí)行之前和之后如何將樣式應(yīng)用于其目標(biāo)。
.fade-out-forwards {
animation: fade-out 1000ms;
animation-fill-mode: forwards;
}
??animation-fill-mode?
? 屬性的參數(shù)有以下四個(gè):
??none?
? :這是默認(rèn)值,當(dāng)動(dòng)畫(huà)未執(zhí)行時(shí),動(dòng)畫(huà)將不會(huì)將任何樣式應(yīng)用于目標(biāo),而是已經(jīng)賦予給該元素的 CSS 規(guī)則來(lái)顯示該元素; ??forwards?
?:目標(biāo)將保留由執(zhí)行期間遇到的最后一個(gè)關(guān)鍵幀計(jì)算值,最后一個(gè)關(guān)鍵幀取決于??animation-direction?
?和??animation-iteration-count?
?的值; ??backwards?
?:動(dòng)畫(huà)將在應(yīng)用于目標(biāo)時(shí)立即應(yīng)用第一個(gè)關(guān)鍵幀中定義的值,并在??animation-delay?
?期間保留此值。 第一個(gè)關(guān)鍵幀取決于??animation-direction?
?的值; ??both?
?:動(dòng)畫(huà)將遵循 ??forwards?
? 和 ??backwards?
? 的規(guī)則,從而在兩個(gè)方向上擴(kuò)展動(dòng)畫(huà)屬性。
動(dòng)態(tài)動(dòng)畫(huà)
??keyframe?
? 動(dòng)畫(huà)實(shí)現(xiàn)了基本的動(dòng)畫(huà)效果,將它們與CSS變量一起使用的時(shí)候可以定義更加復(fù)雜的效果。
.bounce-box {
animation: bounce 300ms alternate infinite cubic-bezier(0.2, 0.65, 0.6, 1);
}
@keyframes bounce {
from {
transform: translateY(0px);
}
to {
transform: translateY(62px);
}
}
CSS動(dòng)畫(huà)是可以通用的和可重用的,但是這個(gè)動(dòng)畫(huà)總是會(huì)讓一個(gè)元素彈跳 62px。如果不同的元素可以提供不同的“彈跳高度”,就提高了動(dòng)畫(huà)的靈活性。
使用CSS變量,就可以做到:
@keyframes bounceY {
from {
transform: translateY(0px);
}
to {
transform: translateY(var(--bounce-offset));
}
}
.bounceY-box {
float: left;
animation: bounce alternate infinite cubic-bezier(0.2, 0.65, 0.6, 1);
}
.bounceY-box.one {
--bounce-offset: 62px;
animation-duration: 200ms;
}
.bounceY-box.two {
--bounce-offset: 32px;
animation-duration: 300ms;
}
.bounceY-box.three {
--bounce-offset: -40px;
animation-duration: 400ms;
}
總結(jié)
CSS 在近幾年發(fā)生了多大的變化,功能變得越來(lái)越強(qiáng)大,促進(jìn)未來(lái) WEB 應(yīng)用變得更佳豐富。
本文摘自 :https://blog.51cto.com/u