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