當前位置:首頁 > IT技術(shù) > Web編程 > 正文

CSS交互動畫指南之keyframes
2021-09-24 14:52:02

CSS交互動畫指南之keyframes_css

過去 WEB 需要實現(xiàn)交互動畫效果是使用 ??flash?? 、??javascript??、??Gif??,近年來隨著 ??flash?? 的淘汰,??javascript?? 和 ??CSS?? 功能的增強,使得現(xiàn)代 WEB 應用的交互越來越豐富。借此總結(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?? 動畫也是可以通用的和可重用的,可以將它們應用到特定選擇器的 ??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?? 信心之路的最大障礙。例如希望元素淡出,動畫本身運行良好,但是當它結(jié)束時,元素會重新出現(xiàn)一下導致閃現(xiàn)的效果:

.fade-out {
animation: fade-out 1000ms;
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}

為什么元素會執(zhí)行完動畫后重新再閃現(xiàn)一下并完全可見了,這是因為 ??from?? 和 ??to?? 塊中的聲明只在動畫運行時有效。

??1000ms?? 動畫完成過后,元素就按照CSS聲明顯示,而透明度默認情況下是不透明的。因此動畫完成后透明度又恢復到不透明了。

解決這個問題的一種方法是在動畫之外聲明透明度,如下:

.fade-out-2 {
animation: fade-out 1000ms;
opacity: 0;
}

上面的方案雖然解決了問題,但這不是最佳的方式。最佳的方式是使用屬性 ??animation-fill-mode?? ,設(shè)置CSS動畫在執(zhí)行之前和之后如何將樣式應用于其目標。

.fade-out-forwards {
animation: fade-out 1000ms;
animation-fill-mode: forwards;
}

??animation-fill-mode?? 屬性的參數(shù)有以下四個:

??none?? :這是默認值,當動畫未執(zhí)行時,動畫將不會將任何樣式應用于目標,而是已經(jīng)賦予給該元素的 CSS 規(guī)則來顯示該元素; ??forwards??:目標將保留由執(zhí)行期間遇到的最后一個關(guān)鍵幀計算值,最后一個關(guān)鍵幀取決于??animation-direction??和??animation-iteration-count??的值; ??backwards??:動畫將在應用于目標時立即應用第一個關(guān)鍵幀中定義的值,并在??animation-delay??期間保留此值。 第一個關(guān)鍵幀取決于??animation-direction??的值; ??both??:動畫將遵循 ??forwards?? 和 ??backwards?? 的規(guī)則,從而在兩個方向上擴展動畫屬性。

動態(tài)動畫

??keyframe?? 動畫實現(xiàn)了基本的動畫效果,將它們與CSS變量一起使用的時候可以定義更加復雜的效果。

.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 應用變得更佳豐富。

本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務立即開通 >