SS3過渡動畫函數總結,總結了動畫函數屬性transition-timing-function里面的值的用法,方便大家以后使用該屬性時就知道有這么一回事!
代碼如下:
html結構:
css樣式:
在網頁設計和前端開發中,動效不僅能夠提升用戶體驗,還能增強用戶交互的趣味性和直觀性。CSS3中的transition屬性為開發者提供了一種簡單而強大的工具,用于實現元素從一種樣式逐漸平滑地過渡到另一種樣式的動畫效果。本文將深入探討CSS3 transition的基本概念、語法結構以及如何實際應用它來創建豐富的動態效果。
CSS3 Transition 是一種無需JavaScript即可讓元素在不同狀態之間平滑轉換的方法。當一個元素的CSS屬性值發生變化時(通常由用戶操作如鼠標懸停、點擊或頁面加載等觸發),Transition允許我們定義一個時間區間,在這個時間段內,CSS屬性的變化將會以平滑的動畫形式呈現出來。
Transition由以下四個子屬性組成:
transition-property指定了哪些CSS屬性的變化會觸發過渡動畫。它可以接受單個屬性名,多個屬性名(用逗號分隔),或者關鍵字all表示所有可動畫的屬性。
.example {
transition-property: background-color, transform;
}
transition-duration定義了過渡動畫持續的時間,單位通常是秒(s)或毫秒(ms)。
.example {
transition-duration: 0.5s;
}
transition-timing-function決定了過渡過程中速度變化的方式,可以是預定義的關鍵字(如ease, linear, ease-in, ease-out, ease-in-out),也可以是貝塞爾曲線函數(如cubic-bezier())。
.example {
transition-timing-function: ease-in-out;
}
transition-delay指定了動畫開始之前的延遲時間。
.example {
transition-delay: 0.2s;
}
此外,為了簡化書寫,上述四個子屬性可以合并寫成簡寫形式:
.example {
transition: property duration timing-function delay;
}
例如:
.example {
transition: background-color 0.5s ease-in-out 0.2s, transform 0.5s;
}
假設我們有一個按鈕,希望當鼠標懸停在其上時背景色能漸變,并且大小改變。
<button class="example-button">Hover Me</button>
.example-button {
background-color: #ccc;
width: 100px;
height: 50px;
transition: background-color 0.5s, width 0.5s, height 0.5s;
}
.example-button:hover {
background-color: #ff0000;
width: 120px;
height: 60px;
}
在這個例子中,當鼠標懸停在按鈕上時,其背景顏色會在0.5秒內從灰色漸變到紅色,同時寬度和高度也會平滑地增加。
CSS3 Transition是一種簡潔高效的動畫解決方案,尤其適用于那些只需簡單過渡效果的場景。通過靈活運用Transition,我們可以輕松構建出更加生動有趣的Web界面,進一步提升用戶體驗。然而,對于更復雜的動畫需求,可能需要借助于CSS3的另一項強大功能——關鍵幀動畫(@keyframes)。無論如何,理解和掌握Transition都將為你的前端動畫之旅打下堅實的基礎。
建議多看幾遍~~。然后動手去寫寫,學編程只有多動手才能有感覺。
內置組件:
它在任意別的組件中都可以被使用,無需注冊。
Vue 提供了兩個內置組件,可以幫助你制作基于狀態變化的過渡和動畫:
<Transition> 會在一個元素或組件進入和離開 DOM 時應用動畫。本章節會介紹如何使用它。
<TransitionGroup> 會在一個 v-for 列表中的元素或組件被插入,移動,或移除時應用動畫
進入或者離開的動畫
<script lang="ts" setup>
import { ref } from 'vue'
const show=ref(true)
</script>
<template>
<div class="container">
<button @click="show=!show">點擊切換按鈕狀態</button>
<Transition>
<p v-if="show">hello</p>
</Transition>
</div>
</template>
<style lang="scss" scoped>
.container {
/* 下面我們會解釋這些 class 是做什么的 */
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
}
</style>
<Transition> 僅支持單個元素或組件作為其插槽內容。如果內容是一個組件,這個組件必須僅有一個根元素。
當一個 <Transition> 組件中的元素被插入或移除時,會發生下面這些事情:
Vue 會自動檢測目標元素是否應用了 CSS 過渡或動畫。如果是,則一些 CSS 過渡 class 會在適當的時機被添加和移除。
如果有作為監聽器的 JavaScript 鉤子,這些鉤子函數會在適當時機被調用。
如果沒有探測到 CSS 過渡或動畫、也沒有提供 JavaScript 鉤子,那么 DOM 的插入、刪除操作將在瀏覽器的下一個動畫幀后執行。
v-enter-from:進入動畫的起始狀態。在元素插入之前添加,在元素插入完成后的下一幀移除。
v-enter-active:進入動畫的生效狀態。應用于整個進入動畫階段。在元素被插入之前添加,在過渡或動畫完成之后移除。這個 class 可以被用來定義進入動畫的持續時間、延遲與速度曲線類型。
v-enter-to:進入動畫的結束狀態。在元素插入完成后的下一幀被添加 (也就是 v-enter-from 被移除的同時),在過渡或動畫完成之后移除。
v-leave-from:離開動畫的起始狀態。在離開過渡效果被觸發時立即添加,在一幀后被移除。
v-leave-active:離開動畫的生效狀態。應用于整個離開動畫階段。在離開過渡效果被觸發時立即添加,在過渡或動畫完成之后移除。這個 class 可以被用來定義離開動畫的持續時間、延遲與速度曲線類型。
v-leave-to:離開動畫的結束狀態。在一個離開動畫被觸發后的下一幀被添加 (也就是 v-leave-from 被移除的同時),在過渡或動畫完成之后移除。
v-enter-active 和 v-leave-active 給我們提供了為進入和離開動畫指定不同速度曲線的能力,我們將在下面的小節中看到一個示例。
我們可以給 Transition 組件傳一個 name prop 來聲明一個過渡效果名:
<Transition name="fade">
...
</Transition>
對于一個有名字的過渡效果,對它起作用的過渡 class 會以其名字而不是 v 作為前綴。比如,上方例子中被應用的 class 將會是 fade-enter-active 而不是 v-enter-active。這個“fade”過渡的 class 應該是這樣:
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
使用不同的持續時間和速度曲線來過渡多個屬性示例:
<script lang="ts" setup>
import { ref } from 'vue'
const show=ref(true)
</script>
<template>
<div class="container">
<button @click="show=!show">點擊切換按鈕狀態</button>
<Transition name="slide-fade">
<p v-if="show">持續時間和速度曲線控制</p>
</Transition>
</div>
</template>
<style lang="scss" scoped>
.container {
/*
進入和離開動畫可以使用不同
持續時間和速度曲線。
*/
.slide-fade-enter-active {
transition: all 0.3s ease-out;
}
.slide-fade-leave-active {
transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter-from,
.slide-fade-leave-to {
transform: translateX(20px);
opacity: 0;
}
}
</style>
原生 CSS 動畫和 CSS transition 的應用方式基本上是相同的,只有一點不同,那就是 *-enter-from 不是在元素插入后立即移除,而是在一個 animationend 事件觸發時被移除。
對于大多數的 CSS 動畫,我們可以簡單地在 _-enter-active 和 _-leave-active class 下聲明它們。下面是一個示例:
<script lang="ts" setup>
import { ref } from 'vue'
const show=ref(true)
</script>
<template>
<div class="container">
<button @click="show=!show">點擊切換狀態</button>
<Transition name="bounce">
<p v-if="show" style="text-align: center">這是 CSS transition 示例</p>
</Transition>
</div>
</template>
<style lang="scss" scoped>
.container {
text-align: center;
.bounce-enter-active {
animation: bounce-in 0.5s;
}
.bounce-leave-active {
animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.25);
}
100% {
transform: scale(1);
}
}
}
</style>
你也可以向 <Transition> 傳遞以下的 props 來指定自定義的過渡 class:
安裝 animate.css 動畫庫,(已安裝的可以忽略)
pnpm install animate.css --save
<!-- 假設你已經在頁面中引入了 Animate.css -->
<script lang="ts" setup>
import { ref } from 'vue'
import 'animate.css'
const show=ref(true)
</script>
<template>
<div class="container">
<button @click="show=!show">點擊切換狀態</button>
<Transition
name="custom-classes"
enter-active-class="animate__animated animate__zoomIn "
leave-active-class="animate__animated animate__zoomOut"
>
<p v-if="show">引入animate動畫庫</p>
</Transition>
</div>
</template>
<style lang="scss" scoped>
.container {
text-align: center;
}
</style>
Vue 需要附加事件監聽器,以便知道過渡何時結束。可以是 transitionend 或 animationend,這取決于你所應用的 CSS 規則。如果你僅僅使用二者的其中之一,Vue 可以自動探測到正確的類型。
然而在某些場景中,你或許想要在同一個元素上同時使用它們兩個。舉例來說,Vue 觸發了一個 CSS 動畫,同時鼠標懸停觸發另一個 CSS 過渡。此時你需要顯式地傳入 type prop 來聲明,告訴 Vue 需要關心哪種類型,傳入的值是 animation 或 transition:
偽代碼:
<Transition type="animation">...</Transition>
盡管過渡 class 僅能應用在 <Transition> 的直接子元素上,我們還是可以使用深層級的 CSS 選擇器,在深層級的元素上觸發過渡效果。
<Transition name="nested">
<div v-if="show" class="outer">
<div class="inner">
Hello
</div>
</div>
</Transition>
/* 應用于嵌套元素的規則 */
.nested-enter-active .inner,
.nested-leave-active .inner {
transition: all 0.3s ease-in-out;
}
.nested-enter-from .inner,
.nested-leave-to .inner {
transform: translateX(30px);
opacity: 0;
}
/* ... 省略了其他必要的 CSS */
我們甚至可以在深層元素上添加一個過渡延遲,從而創建一個帶漸進延遲的動畫序列:
/* 延遲嵌套元素的進入以獲得交錯效果 */
.nested-enter-active .inner {
transition-delay: 0.25s;
}
然而,這會帶來一個小問題。默認情況下,<Transition> 組件會通過監聽過渡根元素上的第一個 transitionend 或者 animationend 事件來嘗試自動判斷過渡何時結束。而在嵌套的過渡中,期望的行為應該是等待所有內部元素的過渡完成。
在這種情況下,你可以通過向 <Transition> 組件傳入 duration prop 來顯式指定過渡的持續時間 (以毫秒為單位)。總持續時間應該匹配延遲加上內部元素的過渡持續時間:
<Transition :duration="550">...</Transition>
如果有必要的話,你也可以用對象的形式傳入,分開指定進入和離開所需的時間:
<Transition :duration="550">...</Transition>
你可能注意到我們上面例子中展示的動畫所用到的 CSS 屬性大多是 transform 和 opacity 之類的。用這些屬性制作動畫非常高效,因為:
他們在動畫過程中不會影響到 DOM 結構,因此不會每一幀都觸發昂貴的 CSS 布局重新計算。
大多數的現代瀏覽器都可以在執行 transform 動畫時利用 GPU 進行硬件加速。
相比之下,_像 height 或者 margin 這樣的屬性會觸發 CSS 布局變動_,因此執行它們的動畫效果更昂貴,需要謹慎使用。我們可以在 CSS-Triggers(https://csstriggers.com/) 這類的網站查詢哪些屬性會在執行動畫時觸發 CSS 布局變動。
你可以通過監聽 <Transition> 組件事件的方式在過渡過程中掛上鉤子函數:
<Transition
@before-enter="onBeforeEnter"
@enter="onEnter"
@after-enter="onAfterEnter"
@enter-cancelled="onEnterCancelled"
@before-leave="onBeforeLeave"
@leave="onLeave"
@after-leave="onAfterLeave"
@leave-cancelled="onLeaveCancelled"
>
<!-- ... -->
</Transition>
// 在元素被插入到 DOM 之前被調用
// 用這個來設置元素的 "enter-from" 狀態
function onBeforeEnter(el) {}
// 在元素被插入到 DOM 之后的下一幀被調用
// 用這個來開始進入動畫
function onEnter(el, done) {
// 調用回調函數 done 表示過渡結束
// 如果與 CSS 結合使用,則這個回調是可選參數
done()
}
// 當進入過渡完成時調用。
function onAfterEnter(el) {}
// 當進入過渡在完成之前被取消時調用
function onEnterCancelled(el) {}
// 在 leave 鉤子之前調用
// 大多數時候,你應該只會用到 leave 鉤子
function onBeforeLeave(el) {}
// 在離開過渡開始時調用
// 用這個來開始離開動畫
function onLeave(el, done) {
// 調用回調函數 done 表示過渡結束
// 如果與 CSS 結合使用,則這個回調是可選參數
done()
}
// 在離開過渡完成、
// 且元素已從 DOM 中移除時調用
function onAfterLeave(el) {}
// 僅在 v-show 過渡中可用
function onLeaveCancelled(el) {}
這些鉤子可以與 CSS 過渡或動畫結合使用,也可以單獨使用。
在使用僅由 JavaScript 執行的動畫時,最好是添加一個 :css="false" prop。這顯式地向 Vue 表明可以跳過對 CSS 過渡的自動探測。除了性能稍好一些之外,還可以防止 CSS 規則意外地干擾過渡效果。
<Transition
...
:css="false"
>
...
</Transition>
在有了 :css="false" 后,我們就自己全權負責控制什么時候過渡結束了。這種情況下對于 @enter 和 @leave 鉤子來說,回調函數 done 就是必須的。否則,鉤子將被同步調用,過渡將立即完成。
這里是使用 GreenSock 庫(https://gsap.com/)執行動畫的一個示例,你也可以使用任何你想要的庫,比如 Anime.js (https://animejs.com/) 或者 Motion One(https://motion.dev/)。
得益于 Vue 的組件系統,過渡效果是可以被封裝復用的。要創建一個可被復用的過渡,我們需要為 <Transition> 組件創建一個包裝組件,并向內傳入插槽內容:
<!-- MyTransition.vue -->
<script>
// JavaScript 鉤子邏輯...
</script>
<template>
<!-- 包裝內置的 Transition 組件 -->
<Transition
name="my-transition"
@enter="onEnter"
@leave="onLeave">
<slot></slot> <!-- 向內傳遞插槽內容 -->
</Transition>
</template>
<style>
/*
必要的 CSS...
注意:避免在這里使用 <style scoped>
因為那不會應用到插槽內容上
*/
</style>
現在 MyTransition 可以在導入后像內置組件那樣使用了:
<MyTransition>
<div v-if="show">Hello</div>
</MyTransition>
如果你想在某個節點初次渲染時應用一個過渡效果,你可以添加 appear prop:
<Transition appear>
...
</Transition>
除了通過 v-if / v-show 切換一個元素,我們也可以通過 v-if / v-else / v-else-if 在幾個組件間進行切換,只要確保任一時刻只會有一個元素被渲染即可:
<Transition>
<button v-if="docState==='saved'">Edit</button>
<button v-else-if="docState==='edited'">Save</button>
<button v-else-if="docState==='editing'">Cancel</button>
</Transition>
``
在之前的例子中,進入和離開的元素都是在同時開始動畫的,因此我們不得不將它們設為 position: absolute 以避免二者同時存在時出現的布局問題。
然而,很多情況下這可能并不符合需求。我們可能想要先執行離開動畫,然后在其完成之后再執行元素的進入動畫。手動編排這樣的動畫是非常復雜的,好在我們可以通過向 <Transition> 傳入一個 mode prop 來實現這個行為:
<Transition mode="out-in">
...
</Transition>
將之前的例子改為 mode="out-in" 后是這樣:
<Transition> 也支持 mode="in-out",雖然這并不常用。
<Transition> 也可以作用于動態組件之間的切換:
<Transition name="fade" mode="out-in">
<component :is="activeComponent"></component>
</Transition>
<Transition> 的 props (比如 name) 也可以是動態的!這讓我們可以根據狀態變化動態地應用不同類型的過渡:
<Transition :name="transitionName">
<!-- ... -->
</Transition>
這個特性的用處是可以提前定義好多組 CSS 過渡或動畫的 class,然后在它們之間動態切換。
你也可以根據你的組件的當前狀態在 JavaScript 過渡鉤子中應用不同的行為。最后,創建動態過渡的終極方式還是創建可復用的過渡組件,并讓這些組件根據動態的 props 來改變過渡的效果。掌握了這些技巧后,就真的只有你想不到,沒有做不到的了。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。